原文链接:http://blog.csdn.net/jarily/article/details/8679280
1 /****************************************** 2 数据结构: 3 BST(Binary Search Tree),二叉查找树; 4 5 性质: 6 若结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 7 若结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 8 该结点的左、右子树也分别为二叉查找树; 9 10 遍历: 11 对于一个已知的二叉查找树,从小到大输出其节点的值; 12 只需对其进行二叉树的中序遍历即可; 13 即递归地先输出其左子树,再输出其本身,然后输出其右子树; 14 遍历的时间复杂度为O(n); 15 16 查找: 17 对于一个已知的二叉查找树x; 18 在其中查找特定的值k,函数Search返回指向值为k的节点指针; 19 若找不到则返回0,算法时间复杂度为O(h),h为树的高度; 20 理想情况下时间复杂度为lgn; 21 22 最大值和最小值: 23 要查找二叉查找树中具有最小值的元素; 24 只要从根节点开始,沿着左子树找到最左边的节点就可以了; 25 反之沿着右子树查找则可以求最大值; 26 27 插入: 28 从根节点开始插入; 29 如果要插入的值小于等于当前节点的值,在当前节点的左子树中插入; 30 如果要插入的值大于当前节点的值,在当前节点的右子树中插入; 31 如果当前节点为空节点,在此建立新的节点,该节点的值为要插入的值,左右子树为空,插入成功; 32 33 删除: 34 如果该没有子女,直接删除; 35 如果该结点只有一个子女,则删除它,将其子女的父亲改为它的父亲; 36 如果该结点有两个子女,先用其后继替换该节点,其后继的数据一并加在其后; 37 *******************************************/ 38 #include<iostream> 39 #include<cstring> 40 #include<cstdlib> 41 #include<cstdio> 42 #include<climits> 43 #include<algorithm> 44 using namespace std; 45 46 const int N = 100000; 47 int key[N], l[N], r[N], p[N]; 48 int u, node; 49 50 int Search(int x, int k)//查询 51 { 52 if(x == 0 || k == key[x]) 53 return x; 54 if(k < key[x]) 55 return Search(l[x], k); 56 else 57 return Search(r[x], k); 58 } 59 60 int Iterative_Search(int x, int k)//非递归版本的查询 61 { 62 while(x != 0 && k != key[x]) 63 if(k < key[x]) 64 x = l[x]; 65 else 66 x = r[x]; 67 return x; 68 } 69 70 int Minimum(int x) 71 { 72 while(l[x] != 0) 73 x = l[x]; 74 return x; 75 } 76 77 int Maximum(int x) 78 { 79 while(r[x] != 0) 80 x = r[x]; 81 return x; 82 } 83 84 int Successor(int x) 85 { 86 if(r[x] != 0) 87 return Minimum(r[x]); 88 int y = p[x]; 89 while(y != 0 && x == r[y]) 90 { 91 x = y; 92 y = p[y]; 93 } 94 return y; 95 } 96 97 int Predecessor(int x) 98 { 99 if(l[x] != 0) 100 return Maximum(l[x]); 101 int y = p[x]; 102 while(y != 0 && x == l[y]) 103 { 104 x = y; 105 y = p[y]; 106 } 107 return y; 108 } 109 110 void Insert(int &T, int v)//插入结点 111 { 112 if(T == 0) 113 key[T = ++node] = v; 114 else if(v <= key[T]) 115 { 116 p[l[T]] = T; 117 Insert(l[T], v); 118 } 119 else 120 { 121 p[r[T]] = T; 122 Insert(r[T], v); 123 } 124 } 125 126 void Iterative_Insert(int T, int v)//非递归版本插入结点 127 { 128 int y = 0; 129 int x = T; 130 int z = ++node; 131 key[z] = v; 132 while(x != 0) 133 { 134 y = x; 135 if(key[z] < key[x]) 136 x = l[x]; 137 else 138 x = r[x]; 139 } 140 p[z] = y; 141 if(y == 0) 142 key[T] = z; 143 else if(key[z] < key[y]) 144 l[y] = z; 145 else 146 r[y] = z; 147 } 148 149 void Transplant(int T, int u, int v)//移植过程; 150 //把一棵子树u归并到另一棵子树v中,u的父亲变为v的父亲,u的父亲就有了v作为其孩子。 151 { 152 if(p[u] == 0) 153 T = v; 154 else if(u == l[p[u]]) 155 l[p[u]] = v; 156 else 157 r[p[u]] = v; 158 if(v != 0) 159 p[v] = p[u]; 160 } 161 162 void Delete(int T, int z)//删除结点 163 { 164 if(l[z] == 0) 165 Transplant(T, z, r[z]); 166 else if(r[z] == 0) 167 Transplant(T, z, l[z]); 168 else 169 { 170 int y = Minimum(r[z]); 171 if(p[y] != z) 172 { 173 Transplant(T, y, r[y]); 174 r[y] = r[z]; 175 p[r[y]] = y; 176 } 177 Transplant(T, z, y); 178 l[y] = l[z]; 179 p[l[y]] = y; 180 } 181 } 182 183 184 int main() 185 { 186 int n; 187 scanf("%d",&n); 188 for(int i=0; i<n; i++) 189 { 190 int k; 191 scanf("%d",&k); 192 Insert(u, k); 193 } 194 Delete(u, Search(u, 1)); 195 printf("%d\n",Search(u,2)); 196 printf("%d\n",Maximum(u)); 197 return 0; 198 }
时间: 2024-10-23 10:50:03