数据结构基础知识之二叉查找树
许久不动笔写东西了,感觉曾经那些熟悉的基础知识变得模糊起来,从今天起梳理一下一些基本知识,与君共勉,立此为证。
二叉查找树:所有节点满足条件,节点的key值大于其所有左子树节点的key值,小于其所有右子树节点的key值。
插入:当前节点p->key,与所要插入的key值作比较,p->key < key,右转;否则,左转。
删除:假设删除节点x,若x没有孩子,直接删除掉;若x只有一个孩子,x的父亲指向x的孩子,删除x;若x有两个孩子,找出x的中序后继y,y必然至多只有一个孩子,把y值赋予x,最后把y删除。
1 #include <stdio.h> 2 #include <math.h> 3 #include <queue> 4 typedef struct node 5 { 6 int key; 7 struct node *left; 8 struct node *right; 9 }treeNode; 10 11 //tree的最小值 12 treeNode* minimum(treeNode *x) 13 { 14 while(x->left) 15 x = x->left; 16 return x; 17 } 18 19 //tree的最大值 20 treeNode* maximum(treeNode *x) 21 { 22 while(x->right) 23 x = x->right; 24 return x; 25 } 26 //节点x中序后继 27 //1.x有右子树, 右子树的最小值 28 //2.x没有右子树, 找到x最近的祖先y, 满足y的左儿子也是x的祖先 29 treeNode* tree_successor(treeNode *root, int value) 30 { 31 treeNode *p = root; 32 treeNode *parent = NULL; 33 while (p && p->key!=value) 34 { 35 if(p->key < value) 36 p = p->right; 37 else 38 { 39 parent = p; 40 p = p->left; 41 } 42 } 43 //没有找到value值 44 if (p == NULL) 45 { 46 return NULL; 47 } 48 if (p->right != NULL) 49 { 50 return minimum(p->right); 51 } 52 //如果parent为NULL,说明x是中序最后一位 53 return parent; 54 55 } 56 57 treeNode* insert(treeNode *root, int value) 58 { 59 treeNode *newNode = new node; 60 newNode->key = value; 61 newNode->left = NULL; 62 newNode->right = NULL; 63 if(root == NULL) 64 { 65 return newNode; 66 } 67 treeNode *cur = root; 68 treeNode *p; 69 while(cur != NULL) 70 { 71 p = cur; 72 if(cur->key < value) 73 cur = cur->right; 74 else cur = cur->left; 75 } 76 if(p->key < value) 77 p->right = newNode; 78 else p->left = newNode; 79 80 return root; 81 } 82 //删除节点x 83 //x没有孩子,直接删除掉 84 //x只有一个孩子,x的父亲指向x的孩子 85 //x有两个孩子,x的中序后继y, y至多有一个右孩子 x.key <- y.key 删除y 86 void erase(treeNode *root, int value) 87 { 88 treeNode *x = root; 89 treeNode *parent = root; 90 while(x != NULL) 91 { 92 parent = x; 93 if(x->key < value) 94 x = x->right; 95 else if (x->key > value) 96 x = x->left; 97 else break; 98 } 99 //没有找到value值 100 if(x == NULL) 101 return; 102 treeNode *child; 103 child = (x->left == NULL) ? x->right : x->left; 104 //只有一个孩子或者没有孩子 105 if(x->left==NULL || x->right==NULL) 106 { 107 if (parent->left == x) 108 parent->left = child; 109 else parent->right = child; 110 delete x; 111 return; 112 } 113 //x有两个孩子 114 parent = x; 115 treeNode *y = x->right; 116 while(y->left) 117 { 118 parent = y; 119 y = y->left; 120 } 121 x->key = y->key; 122 //删除y 123 if(parent->left == y) 124 parent->left = y->right; 125 else 126 parent->right = y->right; 127 delete y; 128 } 129 130 void midOrder(treeNode *root) 131 { 132 if(root != NULL) 133 { 134 midOrder(root->left); 135 printf("%d ", root->key); 136 midOrder(root->right); 137 } 138 } 139 140 void preOrder(treeNode *root) 141 { 142 if(root != NULL) 143 { 144 printf("%d ", root->key); 145 preOrder(root->left); 146 preOrder(root->right); 147 } 148 } 149 150 int depth(treeNode *root) 151 { 152 if(root == NULL) return 0; 153 154 int left = depth(root->left); 155 int right = depth(root->right); 156 return ((left > right) ? left+1 : right+1); 157 158 } 159 160 int main() 161 { 162 printf("输入排序二叉树的元素 -1表示停止\n"); 163 int a, h; 164 treeNode *root = NULL; 165 while(scanf("%d", &a), a != -1) 166 { 167 root = insert(root, a); 168 } 169 printf("中序输出\n"); 170 midOrder(root); 171 printf("\n前序输出\n"); 172 preOrder(root); 173 printf("\n输入要删除的key值\n"); 174 scanf("%d", &a); 175 erase(root, a); 176 printf("中序输出\n"); 177 midOrder(root); 178 printf("\n前序输出\n"); 179 preOrder(root); 180 181 system("pause"); 182 return 0; 183 }