Skip to content

Commit 90646a5

Browse files
authored
Merge pull request #109 from Gathros/missingexamples
Adding missing examples for Tree Traversal and FFT in C.
2 parents ed793f8 + d5fb209 commit 90646a5

File tree

5 files changed

+232
-144
lines changed

5 files changed

+232
-144
lines changed

chapters/FFT/code/c/fft.c

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
#include <complex.h>
22
#include <math.h>
3+
#include <stdio.h>
34
#include <stdlib.h>
5+
#include <string.h>
46
#include <time.h>
5-
#include <stdio.h>
67

7-
#define PI 3.1415926535897932384626
8+
void dft(double complex *X, const size_t N) {
9+
double complex tmp[N];
10+
for (size_t i = 0; i < N; ++i) {
11+
tmp[i] = 0;
12+
for (size_t j = 0; j < N; ++j) {
13+
tmp[i] += X[j] * cexp(-2.0 * M_PI * I * j * i / N);
14+
}
15+
}
16+
17+
memcpy(X, tmp, N * sizeof(*X));
18+
}
819

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

2334
for (size_t i = 0; i < N / 2; ++i) {
24-
X[i + N / 2] = X[i] - cexp(-2.0 * I * PI * i / N) * X[i + N / 2];
35+
X[i + N / 2] = X[i] - cexp(-2.0 * I * M_PI * i / N) * X[i + N / 2];
2536
X[i] -= (X[i + N / 2]-X[i]);
2637
}
2738
}
2839
}
2940

3041
void bit_reverse(double complex *X, size_t N) {
31-
double complex temp;
32-
unsigned int b;
42+
for (int i = 0; i < N; ++i) {
43+
int n = i;
44+
int a = i;
45+
int count = (int)log2((double)N) - 1;
3346

34-
for (unsigned int i = 0; i < N; ++i) {
35-
b = i;
36-
b = (((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1));
37-
b = (((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2));
38-
b = (((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4));
39-
b = (((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8));
40-
b = ((b >> 16) | (b << 16)) >>
41-
(32 - (unsigned int) log2((double)N));
42-
if (b > i) {
43-
temp = X[b];
44-
X[b] = X[i];
45-
X[i] = temp;
46-
}
47+
n >>= 1;
48+
while (n > 0) {
49+
a = (a << 1) | (n & 1);
50+
count--;
51+
n >>= 1;
4752
}
53+
n = (a << count) & ((1 << (int)log2((double)N)) - 1);
54+
55+
if (n > i) {
56+
double complex tmp = X[i];
57+
X[i] = X[n];
58+
X[n] = tmp;
59+
}
60+
}
4861
}
4962

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

5366
for (int i = 1; i <= log2((double)N); ++i) {
5467
int stride = pow(2, i);
55-
double complex w = cexp(-2.0 * I * PI / stride);
68+
double complex w = cexp(-2.0 * I * M_PI / stride);
5669
for (size_t j = 0; j < N; j += stride) {
5770
double complex v = 1.0;
5871
for (size_t k = 0; k < stride / 2; ++k) {

chapters/FFT/cooley_tukey.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ For some reason, though, putting code to this transformation really helped me fi
7272
{% sample lang="jl" %}
7373
[import:2-11, lang:"julia"](code/julia/fft.jl)
7474
{% sample lang="c" %}
75-
[import:2-11, lang:"julia"](code/julia/fft.jl)
75+
[import:7-19, lang:"c_cpp"](code/c/fft.c)
7676
{% sample lang="cpp" %}
7777
[import:2-11, lang:"julia"](code/julia/fft.jl)
7878
{% sample lang="hs" %}
@@ -117,7 +117,7 @@ In the end, the code looks like:
117117
{% sample lang="jl" %}
118118
[import:14-31, lang:"julia"](code/julia/fft.jl)
119119
{% sample lang="c" %}
120-
[import:9-28, lang:"c_cpp"](code/c/fft.c)
120+
[import:21-40, lang:"c_cpp"](code/c/fft.c)
121121
{% sample lang="cpp" %}
122122
[import:27-57, lang:"c_cpp"](code/c++/fft.cpp)
123123
{% sample lang="hs" %}
Lines changed: 83 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,150 +1,121 @@
1-
#include <stdio.h>
1+
#include "utility.h"
2+
3+
#include <stddef.h>
24
#include <stdlib.h>
3-
#include <string.h>
5+
#include <stdio.h>
46

5-
typedef struct node {
7+
struct node {
68
struct node *children;
7-
int children_num;
8-
int ID;
9-
} node;
10-
11-
typedef struct node_list {
12-
node n;
13-
struct node_list *last_list, *next_list;
14-
} node_list;
15-
16-
typedef struct node_points {
17-
node_list *start_point, *end_point;
18-
} node_points;
19-
20-
void push(node_points *np, node n) {
21-
node_list *temp = (node_list*)malloc(sizeof(node_list));
22-
temp->n = n;
23-
temp->last_list = temp->next_list = NULL;
24-
25-
if (!np->end_point) {
26-
np->start_point = temp;
27-
} else {
28-
np->end_point->next_list = temp;
29-
temp->last_list = np->end_point;
9+
size_t children_size;
10+
int id;
11+
};
12+
13+
struct node create_tree(int rows, size_t num_children) {
14+
struct node n = {NULL, 0, rows};
15+
16+
if (rows > 0) {
17+
n.children = (struct node*)malloc(num_children * sizeof(struct node));
18+
n.children_size = num_children;
19+
for (size_t i = 0; i < num_children; ++i) {
20+
n.children[i] = create_tree(rows - 1, num_children);
21+
}
3022
}
3123

32-
np->end_point = temp;
24+
return n;
3325
}
3426

35-
void stack_pop(node_points *np) {
36-
node_list *temp;
37-
temp = np->end_point;
38-
39-
if (temp) {
40-
np->end_point = temp->last_list;
41-
if (!np->end_point) {
42-
np->start_point = NULL;
27+
void destroy_tree(struct node n) {
28+
if (n.id > 0) {
29+
for (size_t i = 0; i < n.children_size; ++i) {
30+
destroy_tree(n.children[i]);
4331
}
4432

45-
free(temp);
33+
free(n.children);
4634
}
4735
}
4836

49-
void queue_pop(node_points *np) {
50-
node_list *temp;
51-
temp = np->start_point;
52-
if (temp) {
53-
np->start_point = temp->next_list;
54-
if (!np->start_point) {
55-
np->end_point = NULL;
56-
}
37+
void dfs_recursive(struct node n) {
38+
printf("%d\n", n.id);
5739

58-
free(temp);
40+
if (n.children) {
41+
for (size_t i = 0; i < n.children_size; ++i) {
42+
dfs_recursive(n.children[i]);
43+
}
5944
}
6045
}
6146

62-
void create_tree(node *n, int num_row, int num_child) {
63-
n->ID = num_row;
64-
if (num_row == 0) {
65-
return;
47+
void dfs_recursive_postorder(struct node n) {
48+
for (size_t i = 0; i < n.children_size; ++i) {
49+
dfs_recursive_postorder(n.children[i]);
6650
}
6751

68-
n->children = (node *)malloc(num_child * sizeof(*n->children));
69-
n->children_num = num_child;
70-
for (int i = 0; i < num_child; ++i) {
71-
node child;
72-
create_tree(&child, num_row - 1, num_child);
73-
*(n->children + i) = child;
74-
}
52+
printf("%d\n", n.id);
7553
}
7654

77-
void DFS_recursive(node n) {
78-
printf("%d\n", n.ID);
79-
if (!n.children) {
80-
return;
81-
}
82-
83-
for (int i = 0; i < n.children_num; ++i) {
84-
DFS_recursive(n.children[i]);
55+
void dfs_recursive_inorder_btree(struct node n) {
56+
switch (n.children_size) {
57+
case 2:
58+
dfs_recursive_inorder_btree(n.children[0]);
59+
printf("%d\n", n.id);
60+
dfs_recursive_inorder_btree(n.children[1]);
61+
break;
62+
case 1:
63+
dfs_recursive_inorder_btree(n.children[0]);
64+
printf("%d\n", n.id);
65+
break;
66+
case 0:
67+
printf("%d\n", n.id);
68+
break;
69+
default:
70+
printf("This is not a binary tree.\n");
71+
break;
8572
}
8673
}
8774

88-
void DFS_stack(node n) {
89-
node_points stack;
90-
memset(&stack, 0, sizeof(node_points));
91-
push(&stack, n);
92-
node temp;
93-
94-
while (stack.start_point != NULL) {
95-
temp = stack.end_point->n;
96-
printf("%d\n", temp.ID);
97-
stack_pop(&stack);
98-
for (int i = 0; i < temp.children_num; ++i) {
99-
if (!temp.children) {
100-
break;
101-
}
102-
103-
push(&stack, temp.children[i]);
75+
void dfs_stack(struct node n) {
76+
struct stack stk = get_stack(sizeof(struct node*));
77+
stack_push(&stk, &n);
78+
struct node *tmp;
79+
80+
while (!stack_empty(&stk)) {
81+
tmp = (struct node*)stack_pop(&stk);
82+
if (!tmp) {
83+
break;
10484
}
105-
}
106-
}
10785

108-
void BFS_queue(node n) {
109-
node_points queue;
110-
memset(&queue, 0, sizeof(node_points));
111-
push(&queue, n);
112-
node temp;
113-
114-
while (queue.start_point != NULL) {
115-
temp = queue.start_point->n;
116-
printf("%d\n", temp.ID);
117-
queue_pop(&queue);
118-
for (int i = 0; i < temp.children_num; ++i) {
119-
if (!temp.children) {
120-
break;
121-
}
122-
123-
push(&queue, temp.children[i]);
86+
printf("%d\n", tmp->id);
87+
for (size_t i = 0; i < tmp->children_size; ++i) {
88+
stack_push(&stk, &tmp->children[i]);
12489
}
12590
}
91+
92+
free_stack(stk);
12693
}
12794

128-
void destroy_tree(node *n) {
129-
if (n->ID == 0) {
130-
return;
131-
}
95+
void bfs_queue(struct node n) {
96+
struct queue q = get_queue(sizeof(struct node*));
97+
enqueue(&q, &n);
98+
struct node *tmp;
13299

133-
for (int i = 0; i < n->children_num; ++i) {
134-
destroy_tree(n->children + i);
100+
while (!queue_empty(&q)) {
101+
tmp = (struct node*)dequeue(&q);
102+
if (!tmp) {
103+
break;
104+
}
105+
106+
printf("%d\n", tmp->id);
107+
for (size_t i = 0; i < tmp->children_size; ++i) {
108+
enqueue(&q, &tmp->children[i]);
109+
}
135110
}
136111

137-
free(n->children);
112+
free_queue(q);
138113
}
139114

140115
int main() {
141-
node root;
142-
create_tree(&root, 3, 3);
143-
DFS_recursive(root);
144-
//DFS_stack(root);
145-
//BFS_queue(root);
146-
destroy_tree(&root);
116+
struct node root = create_tree(3, 3);
117+
bfs_queue(root);
118+
destroy_tree(root);
147119

148120
return 0;
149121
}
150-

0 commit comments

Comments
 (0)