Data Structure - jjin-choi/study_note GitHub Wiki
1. Intro
// Linked List node
typedef struct _node
{
int data;
struct _node *next;
} NODE;
// global variable. ์ ์ฒด Linked List์ head
NODE *head; // node pointer
// insert front function
void insert_data(int data)
{
NODE *temp;
temp = (NODE*)malloc(sizeof(NODE));
temp->data = data;
temp->next = head;
head = temp;
}
2. Display function
void display(void)
{
NODE *temp;
system("clear");
printf("head");
// until temp is NULL
for (temp=head;temp;temp=temp->next)
printf("->[%d]", temp->data);
printf("\n");
getchar();
}
3. Generalized insert function
- Drawback
1) front insert ๋ง ๊ฐ๋ฅ ํน์ ๋งจ ์ ์ฝ์
๊ณผ ๊ทธ๋ ์ง ์์ ๋ ์ฝ๋๊ฐ ๋ฌ๋ผ์ง
2) process ์ 1๊ฐ๋ง ์กด์ฌํ ์ ์์
insert function ์์ head๊ฐ hard coding ๋์ด์์.
- Solution
1) NODE *head ๋ฅผ NODE head ๋ก ๋ณ๊ฒฝํ๊ธฐ
NODE pointer ์์ NODE ๋ก ๋ณ๊ฒฝํ์ฌ ์ค๊ฐ์ node๋ฅผ ์ฝ์
ํ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ code ์ผ๋ฐํ
2) insert function ์ธ์์ NODE pointer ์ถ๊ฐ
์ฌ๋ฌ head๊ฐ ์กด์ฌํ ์ ์๋๋ก ์ง์ญ ๋ณ์๋ก ์ค์ ํ ๋์๋ ๋ฐ๋์ `์ด๊ธฐํ` ํด์ฃผ์ด์ผ ํจ
ex) NODE head = {0, };
4. Memory dependency
- Drawback
1) insert_data ์์ malloc์ ์ฌ์ฉํ๋ฉด heap ์ ์ก์ผ๋ผ๊ณ ๊ฐ์ํ๋ code
- Solution
1) memory ํ ๋น/ํด์ง๋ฅผ user์๊ฒ ์์. NODE๋ก ๋ฐฐ์ด ์ ์ธํ์ฌ stack์ ํ ๋นํด๋๋ค.
(`memory pooling`: ๋ฏธ๋ฆฌ memory๋ฅผ ์ก์๋ ์ผ๋ก์จ ์๋ ๊ฐ์ , ๋จ memory size๊ฐ ์ ํด์ง.
ํ์ง๋ง ํ์ค ์ธ๊ณ์์๋ ๋ฉ๋ชจ๋ฆฌ limit์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๊ทธ์ ๋ง๊ฒ memory๋ฅผ pooling ํด๋๋ฉด ๋จ.)
โป Stack vs. Heap Memory ์์ญ (code/data/stack/heap)
- code: code, function, control statement
- data: global variable, static
- heap: dynamic (malloc, new) ์๋๊ฐ ๋งค์ฐ ๋๋ฆผ!
- stack: (temp) local variable, parameter (๋งค๊ฐ๋ณ์), return
Link: Memory_Segment
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 typedef struct _node
5 {
6 int data;
7 struct _node *next;
8 } NODE;
9
10 void insert_data(NODE *temp, NODE *head)
11 {
12 temp->next = head->next;
13 head->next = temp;
14 }
15
16 void display(NODE *head)
17 {
18 NODE *temp;
19 printf("[HEAD]");
20 for(temp=head->next;temp;temp=temp->next)
21 printf("->[%d]", temp->data);
22 printf("\n");
23 }
24
25 int main()
26 {
27 int i;
28 NODE head = {0, };
29 NODE temps[7];
30
31 for(i=0;i<7;i++)
32 {
33 temps[i].data = i+1;
34 display(&head);
35 insert_data(temps+i, &head);
36 getchar();
37 }
38 return 0;
39 }
5. Tail node
- Drawback
1) display function ํน์ loop ์์ temp๋ก ์ธํด NULL์ ์ญ์ฐธ์กฐํ๊ฒ ๋ ๊ฒฝ์ฐ
temp->data // ((*temp).data) ์ ๋์ผ
process๊ฐ ๋ฐ๋ก ์ฃฝ๊ฒ ๋๋ค. (๋งค์ฐ ์ํํ code!)
- Solution
1) NULL ์ฐธ์กฐ์ ์ํ์ฑ์ ๋ฐฐ์ ํ๊ธฐ ์ํด dummy tail node๋ฅผ ๋์
ํ์ !
๋งจ ์ฒ์์ head์ tail์ ๋ง๋ค๊ณ , tail ์์ฒด๊ฐ ์๊ธฐ ์์ ์ ๊ฐ๋ฆฌํค๋๋ก ์ด๊ธฐํ ํ๋ค.
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 typedef struct _node
5 {
6 int data;
7 struct _node *next;
8 } NODE;
9
10 void insert_data(NODE *temp, NODE *head)
11 {
12 temp->next = head->next;
13 head->next = temp;
14 }
15
16 void display(NODE *head, NODE *tail)
17 {
18 NODE *temp;
19 printf("[HEAD]");
20 for(temp=head->next;temp!=tail;temp=temp->next) // check temp NODE
21 printf("->[%d]", temp->data);
22 printf("->[TAIL]\n");
23 getchar();
24 }
25
26 int main()
27 {
28 int i;
29 NODE tail = {0, &tail}; // tail NODE
30 NODE head = {0, &tail};
31 NODE temps[7];
32
33 for(i=0;i<7;i++)
34 {
35 temps[i].data = i+1;
36 display(&head, &tail);
37 insert_data(temps+i, &head);
38 }
39 return 0;
40 }
6. Circular Linked List
- Drawback
1) ๊ณผ์ฐ tail์ด ํ์ํ๊ฐ? NODE์ ํฌ๊ธฐ๊ฐ ์ปค์ง๋ฉด tail ๋๋ฌธ์ memory ๋ญ๋น ๋ฐ์ํ๊ฒ ๋๋ค.
tail์ด ์์ด๋ tail๊ณผ ๋์ผํ ์ญํ ์ ํ๋๋ก head์๊ฒ tail ์ญํ ๋ถ์ฌ (tail์ ์์ ๊ธฐ ์ํด circular ๋์
)
- Solution
1) ๋งจ ์ฒ์์ head์ ๋ง๋ค๊ณ , head ์์ฒด๊ฐ ์๊ธฐ ์์ ์ ๊ฐ๋ฆฌํค๋๋ก ์ด๊ธฐํ ํ๋ค.
16 void display(NODE *head)
17 {
18 NODE *temp;
19 printf("[HEAD]");
20 for(temp=head->next;temp!=head;temp=temp->next)
21 printf("->[%d]", temp->data);
22 printf("->[HEAD]\n");
23 getchar();
24 }
25
26 int main()
27 {
28 int i;
29 NODE head = {0, &head};
30 NODE temps[7];
31
32 for(i=0;i<7;i++)
33 {
34 temps[i].data = i+1;
35 display(&head);
36 insert_data(temps+i, &head);
37 }
38 return 0;
39 }
7. reserve function
- Drawback
1) singular linked list ์ ํ๊ณ์ (reverse ๋ฐฉํฅ)
- Solution
1) linked list๋ฅผ reverse ํ๋ function ์ ๋ง๋ค์ !
##### ๋ค์ ํด๋ณด๊ธฐ !!
26 void reverse(NODE *head)
27 {
28 NODE *prev = head;
29 NODE *curr = prev->next;
30 NODE *next;
31
32 while(curr != head)
33 {
34 next = curr->next;
35 curr->next = prev;
36
37 prev = curr;
38 curr = next;
39 }
40 curr->next = prev;
41 }
8. Double Linked List
1 #include <stdio.h>
2
3 typedef struct _node
4 {
5 int data;
6 struct _node *prev;
7 struct _node *next;
8 } NODE;
9
10 NODE node;
11
12 void __insert_data(NODE *prev, NODE *temp, NODE *next)
13 {
14 temp->next = next;
15 next->prev = temp;
16 temp->prev = prev;
17 prev->next = temp;
18 }
19
20 void insert_front(NODE *temp, NODE *head)
21 {
22 __insert_data(head, temp, head->next);
23 }
24
25 void insert_back(NODE *temp, NODE *head)
26 {
27 __insert_data(head->prev, temp, head);
28 }
9. Type dependency (void pointer)
3 typedef struct _node
4 {
5 void *data;
6 struct _node *prev;
7 struct _node *next;
8 } NODE;
9
10 NODE node;
11
12 typedef struct
13 {
14 char name[20];
15 } EMPLOYEE;
// loose coupling ์ ๋ฌธ์ ์
// node๊ฐ ๋จผ์ ์์ด์ง๊ฑฐ๋ (dangling pointer) data๊ฐ ๊ฐ๋ฆฌํค๋ ์ ๋ณด๊ฐ ๋จผ์ ์์ด์ง๊ฒ (null ์ฐธ์กฐ) ๋ ๊ฒฝ์ฐ
// ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ผ๋ฏ๋ก node์ data์ ํ ๋น๊ณผ ํด์ง ์์ ์ ํญ์ ์ผ์น ์์ผ์ผ ํ๋ค.
โป loose coupling : Loose coupling is an approach to interconnecting the components in a system or network so that those components, also called elements, depend on each other to the least extent practicable. Coupling refers to the degree of direct knowledge that one element has of another.
Pros: The benefit is that it's much easier to swap other pieces of code/modules/objects/components when the pieces aren't dependent on one another.
Cons: Dangling pointers arise during object destruction, when an object that has an incoming reference is deleted or deallocated, without modifying the value of the pointer, so that the pointer still points to the memory location of the deallocated memory.
10. Type dependency (sizeof)
node์ data๋ฅผ ๋ฃ์ง ๋ง๊ณ , data์ node๋ฅผ ๋ฃ์ด๋ผ !
๊ทธ๋ฆฌํ๋ฉด type dependency ๋ ์์ ๊ณ memory ๋๊ธฐํ ๋ฌธ์ ๋ ํด๊ฒฐํ ์ ์์ ๊ฒ์ด๋ค ~
data์ node (prev pointer, next pointer) ๋ค์ ์๋ก์ node๋ค์ ๊ฐ๋ฆฌํจ๋ค.
์ฆ, node๊ฐ data๋ฅผ ๊ฐ๋ฆฌํจ ๊ฒ ์๋๋ผ node ์์ฒด๋ฅผ ๊ฐ๋ฆฌํค๊ธฐ ๋๋ฌธ์ data ์์กด์ฑ๋ ์์ด์ง๊ณ
data๋ฅผ ์์จ ๋ data๋ฅผ ์์จ ๋, node๋ ๊ฐ์ด ์์ด์ง๊ธฐ ๋๋ฌธ์ memory ๋๊ธฐํ๋ ์์ด์ง๋ค.
4 typedef struct _node
5 {
6 struct _node *prev;
7 struct _node *next;
8 } NODE;
9
10 NODE node;
11
12 typedef struct
13 {
14 char name[20]; // padding -> maybe 8 byte * x
15 NODE list;
16 } EMPLOYEE;
17
37 void display(NODE *head)
38 {
39 EMPLOYEE *emp;
40 NODE *temp;
41
42 printf ("[HEAD]");
43 for (temp=head->next; temp != head; temp=temp->next)
44 {
45 emp = (EMPLOYEE*)((char*)temp - (sizeof(EMPLOYEE) - sizeof(NODE)));
46 printf ("<->[%s]", emp);
47 }
48 printf("<->[HEAD]\n");
49 }
50
51 int main()
52 {
53 NODE head = {&head, &head}; // dummy head
54 EMPLOYEE emp[M] = { {"TEST1"}, {"TEST2"}, {"TEST3"} };
55
56 int i;
57
58 for (i=0;i<M;i++)
59 {
60 insert_back( &emp[i].list, &head );
61 display(&head);
62 }
63
64 return 0;
65 }
11. Type dependency (container_of)
sizeof ๋ฅผ ์ฌ์ฉํ๋ฉด 1๊ฐ์ node์ 1๊ฐ์ list๋ง ๊ฐ์ง ์ ์๋ค.
โป pointer ๋ฅผ ์ซ์๋ก ๋ณ๊ฒฝํ๊ณ ์ถ์ผ๋ฉด int ๊ฐ ์๋ unsigned long ์ ์ฌ์ฉ ํด์ผ ํ๋ค ! (32bit 64bit ์์๋ ํธํ ๊ฐ๋ฅ)
12 typedef struct
13 {
14 char name[20];
15 NODE list1;
16 NODE list2;
17
18 } EMPLOYEE;
39 void display(NODE *head)
40 {
41 EMPLOYEE *emp;
42 NODE *temp;
43
44 printf ("[HEAD]");
45 for (temp=head->next; temp != head; temp=temp->next)
46 {
47 emp = (EMPLOYEE*)((char*)temp - (unsigned long)(&((EMPLOYEE*)0)->list2));
48 printf ("<->[%s]", emp);
49 }
50 printf("<->[HEAD]\n");
51 }
// container of - ์ผ๋ฐํ๋ฅผ ํ๊ธฐ ์ํด macro๋ฅผ ์ง์ํ์ !
1 #include <stdio.h>
2 #define container_of(ptr, type, member) \
3 (type*)((char*)ptr - (unsigned long)&((type*)0)->member)
4
5 typedef struct
6 {
7 int a;
8 int b;
9 int c;
10 } AA;
11
12 int main()
13 {
14 AA aa = {1, 2, 3};
15 int *temp = &aa.c;
16
17 AA *p = container_of(temp, AA, c);
18 // AA *p = (AA*)((char*)temp - (unsigned long)(&((AA*)0)->c));
19
20 printf ("[TEST] a, b, c : %d %d %d\n", p->a, p->b, p->c);
21 return 0;
22 }
โป gcc -E ๋ฅผ ํตํด ์ ์ฒ๋ฆฌ ํ์ธํ ์ ์์
12. open source example
macro๋ const ๋ฅผ ์ฌ์ฉํ ์ ์์.
macro์ ์ฌ์ฉ๋๋ ์ธ์๋ type์ ์ง์ ํ ์ ์๊ณ symbol๋ง ์ง์ ํ ์ ์์
โ const๋ฅผ ํ๋ด๋ด๊ธฐ ์ํด์ ๋ด์ฅ macro๋ฅผ ์ฌ์ฉํ์ !
1 #include <stdio.h>
2
3 #define __FOO(x) \
4 printf("data = %d\n", *(x))
5
6 #define FOO(x) \
7 const typeof(*(x)) *__x = x; \
8 __FOO(__x)
9
2์ค ์ด์์ macro์์๋ do while ๋ฌธ์ ์ฌ์ฉํด์ผ ํ์ง๋ง, ์ด๋ฅผ macro์ ์ฌ์ฉํ ๊ฒฝ์ฐ do while ๋ฌธ์ ์ ์ด๋ฌธ์ด๊ธฐ ๋๋ฌธ์ return ๊ฐ์ ๋ฐ์์ฌ ์ ์๋ค.
โ return ๊ฐ์ ๊ฐ๋ macro๋ฅผ ์ฐ์ ! do while ๋ฌธ ๋์ ์๊ดํธ๋ฅผ ์ฌ์ฉํ์ ({ ... }) ์ด์ฉํ๊ธฐ
๊ทธ๋ฌ๋ฉด ์ต์ข
expression ๊ฐ์ด return ๊ฐ์ด ๋๋ค. !
์ต์ข
์ฝ๋์๋,
- macro ์์ ์๋๋ const ์ ๋ํ ๊ณ ๋ ค๊ฐ ํฌํจ๋์ด ์์
- macro ์์ ์๋๋ return ๊ฐ์ด ์๋๋ ์๊ดํธ ๋ฌธ๋ฒ์ด ๋ค์ด๊ฐ ์์
13 #define container_of(ptr, type, member) ({ \
14 const typeof( ((type*)0)->member ) *__mptr = (ptr); \
15 (type*)( (char*)__mptr - offsetof(type, member) );}) \
1. Intro
- linked list์ ๋ฌธ์ ์
1) ์ต์
์ ๊ฒฝ์ฐ Big O(N), N๋ฒ ์ํํด์ผ ํ๋ค.
- hash
1) bucket pointer๋ก ๋๋๋ค.
2) ๊ฐ node๋ฅผ insertํ ๋ hash ๊ฐ์ ๊ณ์ฐํ์ฌ ํด๋น๋๋ ๋ฐ์ ๋ฃ๋๋ค.
3) memory ๋ฅผ ๋ ์ฌ์ฉํจ์ผ๋ก์จ ๋ถ์ฐ ๋ฐฐ์น๋ฅผ ์ด์ฉํ์ฌ ํจ์จ์ ๋์ธ๋ค.
4) hash function ์ด ์๊ณ ๋ฆฌ์ฆ์ ์ฑ๋ฅ์ ์ข์ง์ฐ์งํ๋ค.
2. Generic hash์ ํ์ ์ค๊ณ ๋ฐ ๊ตฌํ
- hash heads
+ 1์ค ํฌ์ธํฐ *first (๊ธฐ๋ณธ์ ์ผ๋ก NULL)
- hash
+ 1์ค ํฌ์ธํฐ *next
+ 2์ค ํฌ์ธํฐ **pprev โ why? pointer์ node๋ฅผ ๊ฐ์ด ๊ฐ๋ฆฌํค๊ธฐ ์ํด์
1 #include <stdio.h>
2 #include <stdlib.h>
3 #define MAX 8
4
5 #define container_of(ptr, type, member) \
6 (type*)((char*)ptr - (unsigned long)&((type*)0)->member)
7
8 struct hlist_head {
9 struct hlist_node *first;
10 };
11
12 struct hlist_node {
13 struct hlist_node *next, **pprev;
14 };
15
16 typedef struct {
17 int no;
18 struct hlist_node hash;
19 } data;
20
21
22 void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
23 {
24 struct hlist_node *first = h->first;
25
26 n->next = first;
27 if (first)
28 first->pprev = &n->next;
29 h->first = n;
30 n->pprev = &h->first;
31
32 }
33
34 void display(struct hlist_head *h)
35 {
36 int i;
37 struct hlist_node *temp;
38 data *d;
39 system("clear");
40
41 for (i=0; i<MAX; i++)
42 {
43 printf ("[%d]", i);
44 for(temp=h[i].first; temp; temp=temp->next)
45 {
46 d = container_of(temp, data, hash);
47 printf("<->[%d]", d->no);
48 }
49 printf ("\n");
50 }
51 getchar();
52 }
53
54 int hash_function(int n)
55 {
56 return n % MAX;
57 }
58
59 int main(void)
60 {
61 struct hlist_head heads[MAX] = {0,};
62 data d[30] = {0,};
63 int i, sno;
64
65 for (i=0; i<30; i++) {
66 sno = 1000 + i;
67 d[i].no = sno;
68 hlist_add_head( &d[i].hash, &heads[hash_function(sno)]);
69 display(heads);
70 }
71
72
73 return 0;
74 }
// hash function
2 #define GOLDEN_RATIO_PRIME_32 0x9e370001UL
...
32 unsigned int hash_32(unsigned int val, unsigned int bits)
33 {
34 unsigned int hash = val * GOLDEN_RATIO_PRIME_32;
35 return hash >> (32 - bits);
36 }
1. Intro
- Terms
+ root : level = 0
+ level
+ leaf : level = depth of tree
+ degree : ์ต๋ ๊ฐ์ง ์
- ํ๋์ node์์ ๋ค๋ฅธ node๋ก ๊ฐ๋ ๋ฐฉ๋ฒ์ด 1๊ฐ๋ง ์กด์ฌํ๋ฉด tree, 2๊ฐ ์ด์ ์กด์ฌํ ๊ฒฝ์ฐ์๋ graph ๋ผ๊ณ ํ๋ค. ํ๊ณก์ (circle) ์ด 1๊ฐ๋ผ๋ ์กด์ฌํ๋ฉด graph ์ด๋ค.
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 typedef enum { LEFT, RIGHT } FLAG;
5
6 typedef struct _node
7 {
8 int data;
9 struct _node *left;
10 struct _node *right;
11 } NODE;
12
13 NODE *root;
14
15 void insert_data(int data, NODE *ref, FLAG flag)
16 {
17 NODE *temp;
18 temp=malloc(sizeof(NODE));
19 temp->data = data;
20 temp->left = 0;
21 temp->right = 0;
22
23 if(root == 0)
24 {
25 root = temp;
26 return;
27 }
28 if (flag == LEFT) ref->left = temp;
29 else if (flag == RIGHT) ref->right = temp;
30 }
31
32 int main(void)
33 {
34 insert_data(1, root, LEFT);
35 insert_data(2, root, LEFT);
36 insert_data(3, root, RIGHT);
37
38 insert_data(4, root->left, LEFT);
39 insert_data(5, root->left, RIGHT);
40
41 insert_data(6, root->right, LEFT);
42 insert_data(7, root->right, RIGHT);
43
44 return 0;
45 }
2. Tree order traverse
tree๋ ๋น์ ํ ์๋ฃ ๊ตฌ์กฐ์ด๋ฏ๋ก ์ ์ฒด ์ํํ๊ธฐ๊ฐ ์ด๋ ต๋ค.
- pre order: root - left - right
+ 1 2 4 5 3 6 7
- in order: left - root - right
+ 4 2 5 1 6 3 7
- post order: left - right - root
+ 4 5 2 6 7 3 1
32 // pre order
33 void pre_order(NODE *temp)
34 {
35 if (temp == 0) return;
36
37 printf ("%d\n", temp->data);
38 pre_order(temp->left);
39 pre_order(temp->right);
40 }
41
42 // in order
43 void in_order(NODE *temp)
44 {
45 if (temp == 0) return;
46
47 in_order(temp->left);
48 printf("%d\n", temp->data);
49 in_order(temp->right);
50 }
51
52 // post order
53 void post_order(NODE *temp)
54 {
55 if (temp == 0) return;
56
57 post_order(temp->left);
58 post_order(temp->right);
59 printf("%d\n", temp->data);
60 }
3. Tree display function
- in_order ์ํ๋ฅผ ํ์ง๋ง, display ๊ฐ ๊ฑฐ์ธ์ ๋ค์งํ ๊ฒ์ฒ๋ผ ๋๊ธฐ ๋๋ฌธ์ ๋ฐ๋๋ก ์ํ๋ฅผ ํ๋ค !
โป static : ํจ์ scope ์ ํ์ ์ด์ง๋ง, ์ ์ญ ๋ณ์์ด๊ธฐ ๋๋ฌธ์ ํจ์์์ ๊ฐ์ ๊ณ์ ์ ์งํ๊ฒ ๋จ.
ํ์ง๋ง ์ด ํจ์๋ฅผ ์ฌ๋ฌ๋ฒ ํธ์ถํ๊ฒ ๋๋ฉด static ๊ฐ์ด ๊ณ์ ์ ์ง๋๋ค.
- ์ ๋ฐฉ๋ฒ์, tree๊ฐ ์ธ๋ก๋ก ์ถ๋ ฅ๋๋ฏ๋ก ๊ฐ๋ก๋ก ์ถ๋ ฅํ๋ ค๋ฉด array ์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
์ด ๋, display ํจ์์ __display ํจ์๋ฅผ ์ฐ๊ฒ ๋๋๋ฐ,
__display ๋ ๋ฐฐ์ด์ ๊ฐ์ ๋ฃ์ด์ฃผ๋ ์ญํ ์ ํ๋ฉฐ, return ๊ฐ์ผ๋ก 2์ฐจ์ ๋ฐฐ์ด์ ๋๊ฒจ์ค๋ค.
์ด ๋ int(* __function(type *var))[size] ์ด๋ฐ ์์ผ๋ก ํ๋ฉด 2์ฐจ์ ๋ฐฐ์ด์ return ๊ฐ์ผ๋ก ์ค์ ๊ฐ๋ฅ
(๊ณ ๊ธ C๋ฌธ๋ฒ ์ฐธ์กฐ)
- ํ์ง๋ง ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฐฐ์ด๋ ํจ์๋ฅผ ํธ์ถํ ๋๋ง๋ค ์ด๊ธฐํ ๋์ด์ผ ํ๋ฏ๋ก static์ด ์๋ ๋ค๋ฅธ ๊ฑธ ์ฌ์ฉํด๋ณด์ !
call by address ๋ก ๋๊ฒจ์ฃผ์
63 // display
64 int (*__display(NODE *temp))[MAX]
65 {
66 int i;
67 static int row = -1;
68 static int col = 0;
69 static int tree[MAX][MAX] = {0,};
70
71 if (temp == 0) return tree;
72
73 ++row;
74 __display(temp->left);
75 tree[row][col++] = temp->data;
76 __display(temp->right);
77 --row;
78 return tree;
79 }
80
81 void display(NODE *temp)
82 {
83 int (*tree)[MAX];
84 int i, j;
85 tree = __display(temp);
86
87 system("clear");
88 for(i=0; i<MAX; i++)
89 {
90 for (j=0; j<MAX; j++)
91 {
92 if (tree[i][j])
93 printf("%3d", tree[i][j]);
94 else
95 printf("%3c", ' ');
96 }
97 printf("\n");
98 }
99 getchar();
100 }
63 // display final
64 void __display(NODE *temp, int (*tree)[MAX], int *row, int *col)
65 {
66 if (temp == 0) return;
67
68 ++*row;
69 __display(temp->left, tree, row, col);
70 tree[*row][++*col] = temp->data;
71 __display(temp->right, tree, row, col);
72 --*row;
73 }
74
75 void display(NODE *temp)
76 {
77 int row = -1;
78 int col = 0;
79 int tree[MAX][MAX] = {0,};
80 __display(temp, tree, &row, &col);
81
82 system("clear");
83 int i, j;
84
85 for(i=0; i<MAX; i++)
86 {
87 for (j=0; j<MAX; j++)
88 {
89 if (tree[i][j])
90 printf("%3d", tree[i][j]);
91 else
92 printf("%3c", ' ');
93 }
94 printf("\n");
95 }
96 getchar();
97 }
4. Binary search tree insert
16 void insert_data(int data)
17 {
18 NODE *temp, *p=root, *prev;
19 temp = (NODE*)malloc(sizeof(NODE));
20
21 temp->data = data;
22 temp->right = 0;
23 temp->left = 0;
24
25 if (root == 0)
26 {
27 root = temp;
28 return;
29 }
30
31 while(p)
32 {
33 prev = p;
34 if (p->data > data)
35 p = p->left;
36 else if (p->data < data)
37 p = p->right;
38 else
39 return;
40 }
41
42 if (prev->data > data)
43 prev->left = temp;
44 else
45 prev->right = temp;
46 }
- ์๋ก ๋ค์ด์ค๋ ๊ฐ์ด root node ๊ฐ๋ณด๋ค ์์ผ๋ฉด ์ผ์ชฝ, ํฌ๋ฉด ์ค๋ฅธ์ชฝ์
+ ์ด ๊ฒฝ์ฐ O(log2N)
+ ๋ํ ์ค๋ณต์ ํ์ฉํ์ง ์์ผ๋ฏ๋ก ๊ฐ์ ๊ฐ์ด ๋ค์ด์ค๋ฉด ๋ฐ๋ก return;
- insert function
+ curr (pointer)์ root (pointer)๋ถํฐ (*curr = root) ์ถ๋ฐ
+ ํ์ง๋ง curr์ 1์ค ํฌ์ธํฐ๋ก ํ๊ฒ ๋๋ฉด code redundancy
+ ๊ฒฐ๋ก : curr์ 2์ค ํฌ์ธํฐ๋ก ํ๋ค ! __**(**curr = &root)**__
+ ์ด๋ ๊ฒ ํ๋ฉด root == 0 ์ผ ๋์ ๋น๊ต ํ ํ์ ์์
+ ๋ํ, while(curr) ๋์ while(*curr) ์ ์ฌ์ฉํ๊ฒ ๋๋ฉด NULL ์ผ๋ ์๋์ผ๋ก ๋น ์ ธ๋์ด
+ while ๋ฌธ์ ์ํํ๋ ์ค์ ์ ์ ํ ์๋ฆฌ๋ฅผ ๋ง๋๋ฉด, curr๋ NULL ์ ๊ฐ๋ฆฌํค๋๊ฒ ์๋๋ผ curr ๊ฐ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ์ left๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋จ.
+ left๋ NULL ์ด์ง๋ง left์ ๋ฒ์ง๋ฅผ ๊ฐ๋ฆฌํค๊ธฐ ๋๋ฌธ์ curr๋ NULL์ ์๋
+ while ๋ฌธ์ ๋น ์ ธ๋์ค๋ฉด *curr = temp; ๋ผ๊ณ ๋ง ๋ฃ์ผ๋ฉด ๋จ.
+ ์ฆ, curr์ root ๋ผ๋ pointer๋ฅผ ๊ฐ๋ฆฌํค๋ pointer ๊ฐ ๋๋ค.
48 void insert_data_final(int data)
49 {
50 NODE *temp;
51 NODE **curr = &root;
52
53 temp = (NODE*)malloc(sizeof(NODE));
54 temp->data = data;
55 temp->right = 0;
56 temp->left = 0;
57
58 while(*curr)
59 {
60 if ( (*curr)->data > data )
61 curr = &(*curr)->left;
62 else if ( (*curr)->data < data )
63 curr = &(*curr)->right;
64 else
65 return;
66 }
67 *curr = temp;
68 }
5. Binary search tree balance
- balance๊ฐ ๋ง์ง ์๋ tree๋ ์ต์
์ ๊ฒฝ์ฐ O(N) ์ด๋ฉฐ ์ด๋ linked list์ ๋์ผํ๋ค.
- ๋ฐ๋ผ์ ๊ฐ์ด ์ด๋ป๊ฒ ๋ค์ด์ค๋๋ผ๋, balance๋ฅผ ๋ง์ถฐ์ฃผ๋ ๊ฒ ํ์ํ๋ค.
+ 1์ฐจ์ sorted ๋ฐฐ์ด๋ก ๋ง๋ค์ด ์ฃผ๋ __fill ์ด๋ผ๋ ํจ์๋ฅผ ๊ตฌํํ๋ค
+ user interface ๊ฒธ bal ํจ์ : ์ธ์๋ฅผ ์ฑ์ฐ๋ ์ญํ
+ __bal ํจ์๋ bal ์์ mid๋ฅผ ์ฐพ์์ ์ฐ๊ฒฐ์์ผ์ฃผ๋ ์ญํ ์ ํ๋ ํจ์
+ __bal ํจ์๋ return ๊ฐ์ด NODE* ๊ฐ ๋์ด์ผ ํ๋ค.
+ ์ด ๋ __bal ํจ์๋ฅผ ์ฌ๊ท์ ์ผ๋ก ํธ์ถํ๋๋ฐ array ์ size์ธ n > 0 ์ผ๋๋ temp๋ฅผ return ํ๊ณ ๊ทธ ์ธ์๋ 0์ return
- ๊ธฐ์กด์ ๋ค์ด์จ tree๋ฅผ ํ๊ดดํ์ฌ 1์ฐจ ๋ฐฐ์ด๋ก ์ ๋ ฌ ํ ๋ค์ balance tree ๋ง๋ค์ด๋ ๋๋๋ฐ, ์ด๋ ๊ฒ ๋๋ฉด ์ค์๊ฐ balance๊ฐ ์๋๋ค. ์ฃผ๊ธฐ์ ์ผ๋ก balance ํจ์๋ฅผ ํธ์ถํ ํ
๋ฐ, ํธ์ถ ์ ๊น์ง๋ balance๊ฐ ๋ง์ง ์๋๋ค.
- ๋ node๊ฐ 10๋ง๊ฐ ๋๋ code์์๋ tree๋ฅผ ๋ค์ ํ๊ดดํ๊ณ ๋ค์ ๋ง๋ค๊ธฐ์๋ overhead๊ฐ ์๋ค.
- ์๋ก์ด tree๋ค์ด ์ฐ๊ตฌ๋๊ธฐ ์์ ! ๋ฐ๋ก RB tree
1. Intro
- AVL tree : ๊ฐ์ค์น๋ฅผ ๋ฌ์ balance๋ฅผ ๋ง์ถ๋ tree
- 2-3 tree /2-3-4 tree
- B tree / B+ tree / B* tree
- Read Black Tree!!
2. RB Tree insert rule โป node ์ parent๋ฅผ parent ๋ผ๊ณ ํ๊ณ ๊ทธ์ parent๋ฅผ gparent, ๊ทธ๋ฆฌ๊ณ gparent์ ๋๋ค๋ฅธ ์์์ uncle ์ด๋ผ๊ณ ํ๋ค.
-
ground rule !
root ๋ ธ๋๋ก๋ถํฐ ๋ชจ๋ ๋จ๋ง ๋ ธ๋๋ก ๊ฐ๋ ๊ฒฝ๋ก์ ๊ฒ์ ๋ ธ๋์ ์๊ฐ ๊ฐ์ผ๋ฉด !! balance๊ฐ ๋ง๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ๋ค. -
์ฒซ์งธ, ์๋ก์ด ๋ ธ๋๋ RED ์ด๋ค. โ root ๋ ธ๋ ๋ฑ์ฅ์ผ๋ก ๋์งธ ๋ฃฐ๋ก ๋ฐ๋ ค๋จ.
-
์ฒซ์งธ, root ๋ ธ๋๋ ์ธ์ ๋ BLACK ์ด๋ค.
-
์ ์งธ, ๋ถ๋ชจ๊ฐ RED ์ด๋ฉด ํ์ ํ๋ค. โ ๋ค๋ฒ์งธ
- color flip parent color => BLACK gparent color => RED
- ๊ฒฝ์ฌ๋ฅผ ๋ณธ๋ค. R-R ๊ฒฝ์ฌ => rotate_left(gparent) (rotate ์ ์ด๋ฏธ ์์ node๊ฐ ์์ผ๋ฉด ์ ์์ ํ๊ณ ๋ด๋ ค์จ๋ค.)
- ์ ์งธ ๋ฃฐ์, uncle์ด ์์ ๊ฒฝ์ฐ ํด๊ฒฐ๋์ง ์์ผ๋ฏ๋ก ๋ค๋ฒ์งธ ๋ฃฐ๋ก ๋ฐ๋ ค๋๋ค.
-
์ ์งธ, parent๋ RED, uncle๋ RED์ด๋ฉด color flip ๋ง ํ๋ค.
- color filp parent, uncle => BLACK gparent => RED
์ ๋ฆฌํ๋ฉด,
- ์ ์ฌ ๋ฐธ๋ฐ์ค ์กฐ๊ฑด: ๋จ๋ง ๋ ธ๋๊น์ง ๊ฒฝ๋ก ์ค BLACK ๋ ธ๋ ์๊ฐ ๊ฐ์ผ๋ฉด balance๊ฐ ๋ง๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ๋ค.
- root ๋ ธ๋๋ ์ธ์ ๋ BLACK ์ด๋ค.
- ์๋ก์ด ๋ ธ๋๋ RED ์ด๋ค.
- ๋ถ๋ชจ๊ฐ RED, ์ผ์ด๋ RED ์ด๋ฉด color flip ๋ง ํ๋ค.
- ๋ถ๋ชจ๊ฐ RED ์ด๋ฉด color flip ๊ณผ rotate ํ๋ค.
4. RB Tree insert code
1. Intro
- ์ง๋ฌธ : ์ํ๋ฒณ ์์์ 5๋ฒ์งธ ์ฌ๋์ ?
- ๋ฌธ์ ์ : ์ด N๊ฐ ์ค N์ ๊ฐ๊น์ด ์ฌ๋์ ์ฐพ์๋์๋ ์๊ฐ์ด ๋ ์ค๋ ๊ฑธ๋ฆฐ๋ค (์ต์ ์ ๊ฒฝ์ฐ O(N))
- ํด๊ฒฐ์ฑ
: ์ฆ๊ฐ๊ฐ์ ์ถ๊ฐํ๋ค ! (augment) : size ๋ผ๊ณ ๋ถ๋ฅธ๋ค.
- leaf node ์๋ augment = 1 ๋ก setting
- parent node ์๋ child node ๋ค์ augment์ ํฉ + 1 ์ ๋ฃ๋๋ค.
- ์ฐพ๊ณ ์ ํ๋ index i, i์ ๋น๊ตํ๋ ๊ธฐ์ค์ k (์ด๊ธฐ๊ฐ์ ์ผ์ชฝ sub-tree์ augment + 1)
- ๊ธฐ์ค์ k ๋ณด๋ค i๊ฐ ์์ ๋์๋ ์ผ์ชฝ์ผ๋ก ์ด๋
- ์ผ์ชฝ์ผ๋ก ์ด๋ํ ๋์๋ i๋ ๊ทธ๋๋ก ์๊ณ , k๋ ๋ค์ ์ผ์ชฝ sub tree์ augment + 1 ๋ก ๋ค์ setting
- ๊ธฐ์ค์ k ๋ณด๋ค i๊ฐ ํด ๋์๋ ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋
- ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํ ๋์๋ i := i - k, k ๋ ์ผ์ชฝ sub tree์ augment + 1 ๋ก setting (null ์ด๋ฉด 0์ผ๋ก ๋ด)
- ๊ธฐ์ค์ k ์ i๊ฐ ๊ฐ์ ๋ ๋ฐ๋ก ์ฐพ๊ณ ์ ํ๋ ๊ณณ !!
- ์ด๋ ๊ฒ ๋ง๋ค์ด์ง tree๋ฅผ ๋์ ํต๊ณ tree ๋ผ๊ณ ํ๋ค.
- ์ด๋ฐ ์๊ณ ๋ฆฌ์ฆ์ select ์๊ณ ๋ฆฌ์ฆ ์ด๋ผ๊ณ ํ๋ค.
1. Intro
- flexible array ๋ฅผ pointer๋ก ์ก์์, ๋์ ์ผ๋ก memory ํ ๋น
https://github.com/imguru-mooc/opensource-datastructure-algorithm