二叉排序树

二叉排序树其实就是二分法,平均时间复杂度为O(nlogn),以下是本人硬着头皮造的轮子。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 
  5 typedef struct bst_node {
  6     int data;
  7     struct bst_node *lchild, *rchild;
  8 } bst_node;
  9 
 10 /*last_pnode为查找得到的最后一个node指针,成功则指向查找值node,失败则指向查找值得父亲node*/
 11 int find_bst_data(bst_node *node, bst_node **last_pnode, int data)
 12 {
 13     if (node == NULL)
 14         return -1;
 15     if (data == node->data) {
 16         return 0;
 17     } else if (data < node->data) {
 18         if (node->lchild == 0)
 19             return -1;
 20         *last_pnode = node->lchild;
 21     } else {
 22         if (node->rchild == 0)
 23             return -1;
 24         *last_pnode = node->rchild;
 25     }
 26     return find_bst_data(*last_pnode, last_pnode, data);
 27 }
 28 
 29 int insert_bst_data(bst_node **root_pnode, int data)
 30 {
 31     bst_node *last_node = *root_pnode;
 32     bst_node *new_node;
 33     /*在树找不到结果,则插入数据*/
 34     if (find_bst_data(*root_pnode, &last_node, data)) {
 35         new_node = (bst_node *)malloc(sizeof(bst_node));
 36         memset(new_node, 0, sizeof(*new_node));
 37 
 38         if (*root_pnode == NULL) {
 39             /*若树还没创建则创建新树*/
 40             *root_pnode = new_node;
 41         } else if (data < last_node->data) {
 42             last_node->lchild = new_node;
 43         } else {
 44             last_node->rchild = new_node;
 45         }
 46         new_node->data = data;
 47         return 0;
 48     }
 49     return -1;
 50 }
 51 
 52 
 53 int delete_bst_ops(bst_node **pnode)
 54 {
 55     bst_node *pre_node, *temp_node;
 56     if ((*pnode)->rchild == NULL) {
 57         temp_node = (*pnode);
 58         (*pnode) = (*pnode)->lchild;
 59         free((void *)temp_node);
 60 
 61     } else if ((*pnode)->lchild == NULL) {
 62         temp_node = (*pnode);
 63         (*pnode) = (*pnode)->rchild;
 64         free((void *)temp_node);
 65     } else {
 66         temp_node = (*pnode);
 67         pre_node = (*pnode)->lchild;
 68         while (pre_node->rchild != NULL) {
 69             temp_node = pre_node;
 70             pre_node = pre_node->rchild;
 71         }
 72         //若前驱节点(前驱不是右子树)等于目标左子树节点则不执行,直接把目标右子树的节点给前驱
 73         if (temp_node != (*pnode)) {    
 74             temp_node->rchild = pre_node->lchild;
 75             pre_node->lchild = (*pnode)->lchild;
 76         }
 77         pre_node->rchild = (*pnode)->rchild;
 78         free((void *)(*pnode));
 79         *pnode = pre_node;
 80     }
 81     return 0;
 82 
 83 }
 84 
 85 
 86 /*这里为什么不用find_bst_data而自己写递归删除函数?因为要找到树的目标节点的真实存储空间,
 87 如果用find_bst_data则不能对树真实节点修改,若要使用find_bst_data需要在函数里添加父节点指针的参数。
 88 */
 89 int delete_bst_data(bst_node **pnode, int data)
 90 {
 91     if (*pnode == NULL)
 92         return -1;
 93     if (data == (*pnode)->data) {
 94         delete_bst_ops(pnode);
 95         return 0;
 96     } else if (data < (*pnode)->data) {
 97         delete_bst_data(&(*pnode)->lchild, data);
 98     } else {
 99         delete_bst_data(&(*pnode)->rchild, data);
100     }
101 }
102 
103 //中序遍历
104 void in_order_traverse(bst_node *node, int *i)
105 {
106     if (node == NULL)
107         return;
108     in_order_traverse(node->lchild, i);
109     printf("%5d", node->data);
110     if (++(*i) % 10 == 0)
111         printf("\n");
112     in_order_traverse(node->rchild, i);
113 }
114 
115 void swap(int *x, int *y)
116 {
117     int t;
118     t = *x;
119     *x = *y;
120     *y = t;
121 }
122 
123 #define B_SIZE 100
124 int main(int argc, char const **argv)
125 {
126 
127     int i;
128     int n;
129     int buff[B_SIZE];
130     bst_node *bst_root = NULL;
131     srand(time(0));
132     for (i = 0; i < B_SIZE; i++) {
133         *(buff + i) = i;
134     }
135 
136     for (n = B_SIZE; n > 0; n--) {
137         /*随机生成索引,并且和末尾索引的数据交换位置,形成真正的随机且不重复的数据*/
138         swap(buff + rand() % n, buff + n - 1);
139     }
140 
141     printf("-------------the raw data-------------\n");
142     for (i = 0; i < B_SIZE; i++) {
143         printf("%5d", *(buff + i));
144         if ((i + 1) % 10 == 0)
145             printf("\n");
146     }
147     for (i = 0; i < B_SIZE; i++) {
148         insert_bst_data(&bst_root, buff[i]);
149     }
150     printf("-------------the processed data-------------\n");
151     i = 0;
152     in_order_traverse(bst_root, &i);
153     delete_bst_data(&bst_root,  0);
154     delete_bst_data(&bst_root,  50);
155     delete_bst_data(&bst_root, 100);
156     printf("-------------the deleted data-------------\n");
157     i = 0;
158     in_order_traverse(bst_root, &i);
159     return 0;
160 }

以上程序随机生成100个0-99的数,程序不能插入相同的数,修改insert_bst_data这个函数就可以。

查找和增加数据都是比较简单,实现起来就需要依靠c的指针功底。(用全局变量毫无压力)

删除数据需要找到目标数的前驱(或使用后驱),把前驱node替代目标node,若前驱有左子树需要把左子树替代自己的位置。

posted @ 2016-08-10 11:44  Kevin_Hwang  阅读(262)  评论(0编辑  收藏  举报