Skip to content
51 changes: 32 additions & 19 deletions chapters/FFT/code/c/fft.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
#include <complex.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdio.h>

#define PI 3.1415926535897932384626
void dft(double complex *X, const size_t N) {
double complex tmp[N];
for (size_t i = 0; i < N; ++i) {
tmp[i] = 0;
for (size_t j = 0; j < N; ++j) {
tmp[i] += X[j] * cexp(-2.0 * M_PI * I * j * i / N);
}
}

memcpy(X, tmp, N * sizeof(*X));
}

void cooley_tukey(double complex *X, const size_t N) {
if (N >= 2) {
Expand All @@ -21,38 +32,40 @@ void cooley_tukey(double complex *X, const size_t N) {
cooley_tukey(X + N / 2, N / 2);

for (size_t i = 0; i < N / 2; ++i) {
X[i + N / 2] = X[i] - cexp(-2.0 * I * PI * i / N) * X[i + N / 2];
X[i + N / 2] = X[i] - cexp(-2.0 * I * M_PI * i / N) * X[i + N / 2];
X[i] -= (X[i + N / 2]-X[i]);
}
}
}

void bit_reverse(double complex *X, size_t N) {
double complex temp;
unsigned int b;
for (int i = 0; i < N; ++i) {
int n = i;
int a = i;
int count = (int)log2((double)N) - 1;

for (unsigned int i = 0; i < N; ++i) {
b = i;
b = (((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1));
b = (((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2));
b = (((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4));
b = (((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8));
b = ((b >> 16) | (b << 16)) >>
(32 - (unsigned int) log2((double)N));
if (b > i) {
temp = X[b];
X[b] = X[i];
X[i] = temp;
}
n >>= 1;
while (n > 0) {
a = (a << 1) | (n & 1);
count--;
n >>= 1;
}
n = (a << count) & ((1 << (int)log2((double)N)) - 1);

if (n > i) {
double complex tmp = X[i];
X[i] = X[n];
X[n] = tmp;
}
}
}

void iterative_cooley_tukey(double complex *X, size_t N) {
bit_reverse(X, N);

for (int i = 1; i <= log2((double)N); ++i) {
int stride = pow(2, i);
double complex w = cexp(-2.0 * I * PI / stride);
double complex w = cexp(-2.0 * I * M_PI / stride);
for (size_t j = 0; j < N; j += stride) {
double complex v = 1.0;
for (size_t k = 0; k < stride / 2; ++k) {
Expand Down
4 changes: 2 additions & 2 deletions chapters/FFT/cooley_tukey.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ For some reason, though, putting code to this transformation really helped me fi
{% sample lang="jl" %}
[import:2-11, lang:"julia"](code/julia/fft.jl)
{% sample lang="c" %}
[import:2-11, lang:"julia"](code/julia/fft.jl)
[import:7-19, lang:"c_cpp"](code/c/fft.c)
{% sample lang="cpp" %}
[import:2-11, lang:"julia"](code/julia/fft.jl)
{% sample lang="hs" %}
Expand Down Expand Up @@ -117,7 +117,7 @@ In the end, the code looks like:
{% sample lang="jl" %}
[import:14-31, lang:"julia"](code/julia/fft.jl)
{% sample lang="c" %}
[import:9-28, lang:"c_cpp"](code/c/fft.c)
[import:21-40, lang:"c_cpp"](code/c/fft.c)
{% sample lang="cpp" %}
[import:27-57, lang:"c_cpp"](code/c++/fft.cpp)
{% sample lang="hs" %}
Expand Down
195 changes: 83 additions & 112 deletions chapters/tree_traversal/code/c/tree_traversal.c
Original file line number Diff line number Diff line change
@@ -1,150 +1,121 @@
#include <stdio.h>
#include "utility.h"

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

typedef struct node {
struct node {
struct node *children;
int children_num;
int ID;
} node;

typedef struct node_list {
node n;
struct node_list *last_list, *next_list;
} node_list;

typedef struct node_points {
node_list *start_point, *end_point;
} node_points;

void push(node_points *np, node n) {
node_list *temp = (node_list*)malloc(sizeof(node_list));
temp->n = n;
temp->last_list = temp->next_list = NULL;

if (!np->end_point) {
np->start_point = temp;
} else {
np->end_point->next_list = temp;
temp->last_list = np->end_point;
size_t children_size;
int id;
};

struct node create_tree(int rows, size_t num_children) {
struct node n = {NULL, 0, rows};

if (rows > 0) {
n.children = (struct node*)malloc(num_children * sizeof(struct node));
n.children_size = num_children;
for (size_t i = 0; i < num_children; ++i) {
n.children[i] = create_tree(rows - 1, num_children);
}
}

np->end_point = temp;
return n;
}

void stack_pop(node_points *np) {
node_list *temp;
temp = np->end_point;

if (temp) {
np->end_point = temp->last_list;
if (!np->end_point) {
np->start_point = NULL;
void destroy_tree(struct node n) {
if (n.id > 0) {
for (size_t i = 0; i < n.children_size; ++i) {
destroy_tree(n.children[i]);
}

free(temp);
free(n.children);
}
}

void queue_pop(node_points *np) {
node_list *temp;
temp = np->start_point;
if (temp) {
np->start_point = temp->next_list;
if (!np->start_point) {
np->end_point = NULL;
}
void dfs_recursive(struct node n) {
printf("%d\n", n.id);

free(temp);
if (n.children) {
for (size_t i = 0; i < n.children_size; ++i) {
dfs_recursive(n.children[i]);
}
}
}

void create_tree(node *n, int num_row, int num_child) {
n->ID = num_row;
if (num_row == 0) {
return;
void dfs_recursive_postorder(struct node n) {
for (size_t i = 0; i < n.children_size; ++i) {
dfs_recursive_postorder(n.children[i]);
}

n->children = (node *)malloc(num_child * sizeof(*n->children));
n->children_num = num_child;
for (int i = 0; i < num_child; ++i) {
node child;
create_tree(&child, num_row - 1, num_child);
*(n->children + i) = child;
}
printf("%d\n", n.id);
}

void DFS_recursive(node n) {
printf("%d\n", n.ID);
if (!n.children) {
return;
}

for (int i = 0; i < n.children_num; ++i) {
DFS_recursive(n.children[i]);
void dfs_recursive_inorder_btree(struct node n) {
switch (n.children_size) {
case 2:
dfs_recursive_inorder_btree(n.children[0]);
printf("%d\n", n.id);
dfs_recursive_inorder_btree(n.children[1]);
break;
case 1:
dfs_recursive_inorder_btree(n.children[0]);
printf("%d\n", n.id);
break;
case 0:
printf("%d\n", n.id);
break;
default:
printf("This is not a binary tree.\n");
break;
}
}

void DFS_stack(node n) {
node_points stack;
memset(&stack, 0, sizeof(node_points));
push(&stack, n);
node temp;

while (stack.start_point != NULL) {
temp = stack.end_point->n;
printf("%d\n", temp.ID);
stack_pop(&stack);
for (int i = 0; i < temp.children_num; ++i) {
if (!temp.children) {
break;
}

push(&stack, temp.children[i]);
void dfs_stack(struct node n) {
struct stack stk = get_stack(sizeof(struct node*));
stack_push(&stk, &n);
struct node *tmp;

while (!stack_empty(&stk)) {
tmp = (struct node*)stack_pop(&stk);
if (!tmp) {
break;
}
}
}

void BFS_queue(node n) {
node_points queue;
memset(&queue, 0, sizeof(node_points));
push(&queue, n);
node temp;

while (queue.start_point != NULL) {
temp = queue.start_point->n;
printf("%d\n", temp.ID);
queue_pop(&queue);
for (int i = 0; i < temp.children_num; ++i) {
if (!temp.children) {
break;
}

push(&queue, temp.children[i]);
printf("%d\n", tmp->id);
for (size_t i = 0; i < tmp->children_size; ++i) {
stack_push(&stk, &tmp->children[i]);
}
}

free_stack(stk);
}

void destroy_tree(node *n) {
if (n->ID == 0) {
return;
}
void bfs_queue(struct node n) {
struct queue q = get_queue(sizeof(struct node*));
enqueue(&q, &n);
struct node *tmp;

for (int i = 0; i < n->children_num; ++i) {
destroy_tree(n->children + i);
while (!queue_empty(&q)) {
tmp = (struct node*)dequeue(&q);
if (!tmp) {
break;
}

printf("%d\n", tmp->id);
for (size_t i = 0; i < tmp->children_size; ++i) {
enqueue(&q, &tmp->children[i]);
}
}

free(n->children);
free_queue(q);
}

int main() {
node root;
create_tree(&root, 3, 3);
DFS_recursive(root);
//DFS_stack(root);
//BFS_queue(root);
destroy_tree(&root);
struct node root = create_tree(3, 3);
bfs_queue(root);
destroy_tree(root);

return 0;
}

Loading