查找之二叉树查找

1.      查找树的创建(createTree)

假设有如下数组4,1,45,78,345,23,12,3,6,21

首先选定4为root,然后遍历剩下的数字,如果大于等于4则放到4的右侧,小于4放到4的左侧,最后构建成的树:所有的左孩子都小于父节点,所有的右孩子都大于等于父节点。如下图:

 

 

 

2.      遍历查找树(displayTree)

按照左中右的顺序遍历树,结果为:1,3,4,5,12,21,23,45,78,345,遍历的结果就是已经排好序的数字。

 

 

3.      查找树中的节点(searchTree)

从根节点开始,如果大于等于根节点,则查找根节点的右侧;如果小于根节点,则查找根节点的左侧,直到查找到节点。

比如要查找12:

比4大,往右走;

        比45小,往左走;

        比23小,往左走;

        找到12

 

4.      删除树中的节点(deleteNode)

这个是最复杂的,因为删除完节点后要重新构建树,涉及到的情况很多:

a.要删除的node没有左右孩子,有父节点。

如果要删除的node为父节点的左孩子,则将父节点的左孩子指针设置为NULL;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为NULL。最后删除node。

 

b.要删除的node没有左右孩子,没有父节点(即根节点)。

根节点设为NULL,删除node。

 

c.要删除的node有左孩子没右孩子,有父节点

如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的左孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的左孩子。最后删除node。

 

d.要被删除的node有左孩子没有右孩子,没有父节点

        将要被删除的node的左孩子设置为根节点,删除node。

 

e.要删除的node有右孩子没左孩子,有父节点

如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的右孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的右孩子。最后删除node。

 

 f.要被删除的node有右孩子没有左孩子,没有父节点

        将要被删除的node的右孩子设置为根节点,删除node。

 

 g.要被删除的node左右孩子都有,有父节点

将要被删除node的右孩子插入到左孩子中去。如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的左孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的左孩子。最后删除node。

 

h.要被删除的node左右孩子都有,无父节点

将要被删除node的右孩子插入到左孩子中去,父节点修改为要被删除node的左孩子,删除node节点。

 

c代码如下:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 #define SIZE 10
  5 
  6 typedef struct tagNode{
  7         int value;
  8         struct tagNode* left;
  9         struct tagNode* right;
 10 }treeNode;
 11 
 12 //打印数组
 13 void displayArray(int array[],int size){
 14         printf("the array is:");
 15         int i;
 16         for(i=0;i<size;i++){
 17                 printf("%d ",array[i]);
 18         }
 19         printf("\n");
 20 }
 21 
 22 //按左中右顺序遍历树
 23 void displayTree(treeNode* node){
 24         if(node == NULL) return;
 25 
 26         if(node->left != NULL){
 27                 displayTree(node->left);
 28         }
 29 
 30         printf("%d ",node->value);
 31 
 32         if(node->right != NULL){
 33                 displayTree(node->right);
 34         }
 35 }
 36 
 37 //查找以node为节点的树中上是否存在vlaue的节点
 38 treeNode* searchTree(treeNode* node, int value){
 39         if(node->value == value){
 40                 return node;
 41         }else if(node->value > value){
 42                 if(node->left != NULL){
 43                         return searchTree(node->left, value);
 44                 }else{
 45                         return NULL;
 46                 }
 47         }else{
 48                 if(node->right != NULL){
 49                         return searchTree(node->right, value);
 50                 }else{
 51                         return NULL;
 52                 }
 53         }
 54 }
 55 
 56 //查找以node为节点的树中上是否存在vlaue的节点,parent为查找到的节点的父节点。
 57 //dir为1表示parent节点的左节点为查找结果
 58 //dir为2表示parent节点的右节点为查找结果
 59 treeNode* searchTreeWithParent(treeNode* node, treeNode** parent, int* dir, int value){
 60         if(node->value == value){
 61                 return node;
 62         }else if(node->value > value){
 63                 if(node->left != NULL){
 64                         *dir = 1;
 65                         *parent = node;
 66                         return searchTreeWithParent(node->left, parent, dir, value);
 67                 }else{
 68                         return NULL;
 69                 }
 70         }else{
 71                 if(node->right != NULL){
 72                         *dir = 2;
 73                         *parent = node;
 74                         return searchTreeWithParent(node->right, parent, dir, value);
 75                 }else{
 76                         return NULL;
 77                 }
 78         }
 79 }
 80 
 81 //将iNode插入到以node为根节点的树中
 82 void insertNode(treeNode* node, treeNode* iNode){
 83         if(iNode->value >= node->value && node->right != NULL){
 84                 insertNode(node->right, iNode);
 85                 return;
 86         }
 87 
 88         if(iNode->value < node->value && node->left != NULL){
 89                 insertNode(node->left, iNode);
 90                 return;
 91         }
 92 
 93         if(iNode->value >= node->value && node->right == NULL){
 94                 node->right = iNode;
 95         }
 96 
 97         if(iNode->value < node->value && node->left == NULL){
 98                 node->left = iNode;
 99         }
100 }
101 
102 //从以root为根节点的树中删除值为value的节点
103 void deleteNode(treeNode** root, int value){
104         treeNode* parent = NULL;
105         int dir = -1;
106         treeNode* deleteNode = searchTreeWithParent(*root,&parent,&dir,value);
107         if(deleteNode == NULL){
108                 printf("%s\n", "node not found");
109         }else{
110                 if(deleteNode->left == NULL && deleteNode->right == NULL){
111             //对应说明中的a
112                         if(parent != NULL){
113                                 if(dir == 1)
114                                         parent->left = NULL;
115                                 else
116                                         parent->right = NULL;
117                         }else{//对应说明中的b
118                                 *root = NULL;
119                         }
120                 }else if(deleteNode->left != NULL && deleteNode->right == NULL){
121                         //对应说明中的c
122             if(parent != NULL){
123                                 if(dir == 1)
124                                         parent->left = deleteNode->left;
125                                 else
126                                         parent->right = deleteNode->left;
127                         }else{//对应说明中的d
128                                 *root = deleteNode->left;
129                         }
130                 }else if(deleteNode->left == NULL && deleteNode->right != NULL){
131                         //对应说明中的e
132             if(parent != NULL){
133                                 if(dir == 1)
134                                         parent->left = deleteNode->right;
135                                 else
136                                         parent->right = deleteNode->right;
137                         }else{//对应说明中的f
138                                 *root = deleteNode->right;
139                         }
140                 }else{
141                         insertNode(deleteNode->left,deleteNode->right);
142                         //对应说明中的g
143             if(parent != NULL){
144                                 if(dir == 1)
145                                         parent->left = deleteNode->left;
146                                 else
147                                         parent->right = deleteNode->left;
148                         }else{//对应说明中的h
149                                 *root = deleteNode->left;
150                         }
151                 }
152                 free(deleteNode);
153                 deleteNode = NULL;
154         }
155 }
156 
157 //使用array数组中的数,创建以root为根节点的树,
158 void createTree(treeNode** root, int array[], int size){
159         int i;
160 
161         *root = (treeNode*)malloc(sizeof(treeNode));
162         (*root)->value = array[0];
163         (*root)->left = NULL;
164         (*root)->right = NULL;
165 
166         for(i=1;i<size;i++){
167                 treeNode* child = (treeNode*)malloc(sizeof(treeNode));
168                 child->value = array[i];
169                 child->left = NULL;
170                 child->right = NULL;
171                 insertNode(*root, child);
172         }
173 }
174 
175 //删除以node为根节点的树
176 void deleteTree(treeNode* node){
177         if(node == NULL) return;
178 
179         if(node->left != NULL){
180                 deleteTree(node->left);
181         }
182 
183         if(node->right != NULL){
184                 deleteTree(node->right);
185         }
186 
187         if(node->left == NULL && node->right == NULL){
188                 free(node);
189                 node = NULL;
190         }
191 }
192 
193 int main(int argc, char* argv[]){
194 
195         int array[SIZE] = {4,1,45,78,345,23,12,3,6,21};
196         displayArray(array,SIZE);
197 
198         treeNode *root = NULL;
199 
200         createTree(&root, array, SIZE);
201 
202         printf("the tree is(left->middle->right):");
203         displayTree(root);
204         printf("\n");
205 
206         int value = atoi(argv[1]);
207         treeNode* parent = NULL;
208         int dir = -1;
209         printf("search value %d:",value);
210         if(searchTree(root,value) != NULL){
211                 printf("%s\n","exist");
212         }else{
213                 printf("%s\n","not exist");
214         }
215 
216         printf("delete value:%d ",value);
217         deleteNode(&root,value);
218         printf("\n");
219         printf("the tree is(left->middle->right):");
220         displayTree(root);
221         printf("\n");
222 
223         deleteTree(root);
224         return 0;
225 }

 

posted @ 2015-08-26 00:18  鸭子船长  阅读(250)  评论(0编辑  收藏  举报