Advertisement
eddiehy

binary_tree

Dec 5th, 2015
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.22 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. struct _node
  4. {
  5. int data;
  6. struct _node* left;
  7. struct _node* right;
  8. };
  9.  
  10. typedef struct _node node;
  11.  
  12. node *insert_node(node *root, int value)
  13. {
  14. node *new_node;
  15. node *current;
  16. node *parent;
  17. new_node = (node *)malloc(sizeof(node));
  18. new_node->data = value;
  19. new_node->left = NULL;
  20. new_node->right = NULL;
  21. if(root == NULL)
  22. {
  23. return new_node;
  24. }
  25. else
  26. {
  27. current = root;
  28. while(current != NULL)
  29. {
  30. parent = current;
  31. if(current->data > value)
  32. {current = current->left;}
  33. else
  34. {current = current->right;}
  35. }
  36. if(parent->data > value)
  37. {parent->left = new_node;}
  38. else
  39. {parent->right = new_node;}
  40. }
  41. return root;
  42. }
  43.  
  44. node *find_node(node *ptr, int value)
  45. {
  46. while(ptr!=NULL)
  47. {
  48. if(ptr->data==value)
  49. {return ptr;}
  50. else
  51. {
  52. if (ptr->data>value)
  53. {ptr=ptr->left;}
  54. else
  55. {ptr=ptr->right;}
  56. }
  57. }
  58. return NULL;
  59. }
  60. void print_inorder(node *ptr)
  61. {
  62. if(ptr != NULL)
  63. {
  64. print_inorder(ptr->left);
  65. printf("%d ", ptr->data);
  66. print_inorder(ptr->right);
  67. }
  68. }
  69.  
  70. void print_preorder(node *ptr)
  71. {
  72. if(ptr != NULL)
  73. {
  74. printf("%d ", ptr->data);
  75. print_preorder(ptr->left);
  76. print_preorder(ptr->right);
  77. }
  78. }
  79.  
  80. void print_postorder(node *ptr)
  81. {
  82. if(ptr != NULL)
  83. {
  84. print_postorder(ptr->left);
  85. print_postorder(ptr->right);
  86. printf("%d ", ptr->data);
  87. }
  88. }
  89.  
  90. void freeall(node *ptr)
  91. {
  92. if(ptr != NULL)
  93. {
  94. freeall(ptr->left);
  95. freeall(ptr->right);
  96. free(ptr);
  97. }
  98. }
  99.  
  100. void freenode (node *p) /* 此函數將節點還給記憶體 */
  101. {
  102. free(p);
  103. }
  104.  
  105. // 找某值之父節點
  106. node *find_parent(node *ptr, int value, int *pos)
  107. {
  108. node *parent;
  109.  
  110. parent = ptr; // 從ptr開始找
  111. *pos = 0;
  112. while(ptr != NULL)
  113. {
  114. if(ptr->data == value) // 找到目標
  115. return parent; // 回傳此節點之父節點
  116. else
  117. {
  118. parent = ptr;
  119. if(ptr->data > value)
  120. {
  121. *pos = -1; // ptr在parent左子樹
  122. ptr = ptr->left; // 往左找
  123. }
  124. else
  125. {
  126. *pos = 1; // ptr在parent右子樹
  127. ptr = ptr->right; // 往右找
  128. }
  129. }
  130. }
  131. return NULL; // 找不到
  132. }
  133.  
  134. // 刪除節點
  135. node *delete_node(node *root, int value)
  136. {
  137. node *parent;
  138. node *ptr;
  139. node *next;
  140. int pos;
  141.  
  142. parent = find_parent(root, value, &pos); // 從root開始,找value之父節點
  143. if(parent==NULL)
  144. {return NULL;}
  145. if(parent != NULL) // 有找到, 準備刪除
  146. {
  147. switch(pos) // 判斷目前節點再父節點左邊或右邊
  148. {
  149. case -1:
  150. ptr = parent->left;
  151. break;
  152. case 1:
  153. ptr = parent->right;
  154. break;
  155. case 0:
  156. ptr = parent;
  157. break;
  158. }
  159. if(ptr->left == NULL) // 情況1: 節點沒有左子樹 如果要刪的是根節點
  160. {
  161. if(parent == ptr) // 如果要刪的是根節點
  162. root = root->right;
  163. else // 其他
  164. {
  165. if( pos == 1 )
  166. {
  167. //要刪除的節點在父節點右方,所以將父節點的右節點指向刪除節點的右節點
  168. parent->right = ptr->right;
  169. }
  170. else
  171. {
  172. //要刪除的節點在父節點左方,所以將父節點的左節點指向刪除節點的右節點
  173. parent->left = ptr->right;
  174. }
  175. }
  176. free(ptr);
  177. }
  178. else if(ptr->right == NULL) // 情況2: 節點沒有右子樹
  179. {
  180. if(parent != ptr)
  181. {
  182. if( pos == 1 )
  183. {
  184. //要刪除的節點在父節點右方,所以將父節點的右節點指向刪除節點的左節點
  185. parent->right = ptr->left;
  186. }
  187. else
  188. {
  189. //要刪除的節點在父節點左方,所以將父節點的左節點指向刪除節點的左節點
  190. parent->left = ptr->left;
  191. }
  192. }
  193. else
  194. root = root->left;
  195. free(ptr);
  196. }
  197. else // 情況3: 節點有左右子樹
  198. {
  199. parent = ptr;
  200. next = ptr->left; // 找取代點next, 從ptr左邊開始找
  201. if(next->right!=NULL)
  202. {
  203. while(next->right != NULL) // 往左子節點之右子樹找最大值當取代點
  204. {
  205. parent = next; // parent為next之父節點
  206. next = next->right;
  207. }
  208. parent->right = next->left; // 繞過next節點
  209. }
  210. else
  211. {
  212. ptr->left=next->left;
  213. }
  214. ptr->data = next->data; // 取代!!
  215. free(next); // 刪除next (注意: 不是刪除ptr)
  216. }
  217. }
  218. return root; // 回傳此樹
  219. }
  220. int main()
  221. {
  222. int key;
  223. node *root,*ptr;
  224. root=NULL;
  225. int value;
  226.  
  227. while(1)
  228. {
  229. scanf("%d",&key);
  230. switch(key)
  231. {
  232. case 1:
  233. scanf("%d",&value);
  234. root=insert_node(root,value);
  235. break;
  236. case 2:
  237. print_inorder(root);
  238. printf("\n");
  239. break;
  240. case 3:
  241. print_preorder(root);
  242. printf("\n");
  243. break;
  244. case 4:
  245. print_postorder(root);
  246. printf("\n");
  247. break;
  248. case 5:
  249. scanf("%d",&value);
  250. ptr=find_node(root,value);
  251. if(ptr==NULL)
  252. {printf("cannot delete\n");}
  253. else
  254. {
  255. root=delete_node(root,value);
  256. printf("delete %d ok\n",value);//ptr已經刪除,所以要用value來顯示
  257. }
  258. break;
  259. case 6:
  260. scanf("%d",&value);
  261. ptr=find_node(root,value);
  262. if(ptr==NULL)
  263. {printf("not found\n");}
  264. else
  265. {printf("found: %d\n",ptr->data);}
  266. break;
  267. case 8:
  268. freeall(root);
  269. return 0;
  270. }
  271. }
  272. return 0;
  273. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement