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(" "); 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 ", "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(" "); 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 ","exist"); 212 }else{ 213 printf("%s ","not exist"); 214 } 215 216 printf("delete value:%d ",value); 217 deleteNode(&root,value); 218 printf(" "); 219 printf("the tree is(left->middle->right):"); 220 displayTree(root); 221 printf(" "); 222 223 deleteTree(root); 224 return 0; 225 }