Skip to content

Adding missing examples for Tree Traversal and FFT in C. #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 20, 2018
Merged
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