呜呜 写这个东西花了我2天 居然花了两天!!我还要写AVL呢啊啊啊啊啊啊啊!!!!!!
等下还要跑去上自习 大早上起来脸都没洗现在先赶紧发博客 昨晚写出来了独自在其他人都睡着了的宿舍狂喜乱舞。。
迷之想哭 不知道能不能考上。。。。。。
不管能不能考上 活在当下就对了 走好每一步踏踏实实吧!!
删除操作的代码考虑了很多东西,自己写的时候一开始觉得有点抽象,特别是左右孩子链接的处理,还有是否是根结点的判别……
其实也不知道我这个写法对不对,看了一些网上的代码,别人的都写得好简单啊!
先这么写着吧,回头有空了我再思考下有没有更简单的实现方法!如果有网友有好建议也欢迎留言!
1、二叉排序树的定义:
或者是一棵空树,或者是一颗具有以下特性的非空二叉树:
(1)若左(右)子树非空,则右(左)子树上的关键字值均小(大)于根结点的关键字值。
(2)左、右子树本身也分别是一颗二叉树。
2、二叉排序树的特点:
(1)对二叉排序树进行中序遍历可以得到一个递增的有序序列。
(2)维护的时候只需修改指针就可以完成插入和删除操作,平均执行时间为O(log2n)。
(3)平均查找性能取决于树的高度,最糟糕的情况下:由于输入的序列是有序的,形成了倾斜单支二叉树(可以理解为变成一个单链表),查找效率降成O(n)(平均查找长度与单链表相同)。
(4)查找判定树不唯一。
3、二叉排序树的适用场合:
有序表是动态查找表的时候应选择二叉排序树作为其逻辑结构。(静态查找表则合适用顺序表)
4、代码实现
注释详见代码!这里不赘述了!如果有不明白或者有错的地方欢迎留言和指正!
包括:
①二叉排序树的建立(包含插入操作)
②二叉排序树的查找
③二叉排序树的删除
④为了写删除操作还增加了一个判别孩子结点是双亲结点的左孩子or右孩子的小函数……
【注】因为此代码算法是自己思考设计的,自己比较笨拙,可能会有实现很冗余的地方,如果要使用建议参考其他人的版本。。可能只合适做数据结构的学习理解用orz
1 #include<iostream> 2 #include<stdlib.h> 3 #include<cstdio> 4 #include<stack> 5 #include<queue> 6 using namespace std; 7 #define TRUE 1 8 #define FALSE 0 9 #define OK 1 10 #define ERROR 0 11 #define OVERFLOW -2 12 typedef int Status; 13 typedef int ElemType; 14 /*存储结构描述*/ 15 typedef struct BitNode 16 { 17 int data; 18 struct BitNode *lchild,*rchild; 19 } BitNode,*BiTree; 20 /*建立一个二叉排序树*/ 21 /*其实是二叉排序树的插入算法*/ 22 void initTree(BiTree &T,int x) 23 { 24 if(T==NULL) 25 { 26 T=(BitNode*)malloc(sizeof(BitNode)); 27 T->data=x; 28 T->lchild=NULL; 29 T->rchild=NULL; 30 } 31 else 32 { 33 if(x>T->data) 34 initTree(T->rchild,x); 35 else initTree(T->lchild,x); 36 } 37 } 38 /*二叉排序树的结点查找*/ 39 /* 40 1、如果查找成功,返回查找的结点 41 2、如果查找失败 返回NULL(走到了叶子结点的下一层→【NULL】) 42 3、指针p指向结点的双亲结点 43 */ 44 BitNode *BST_Search(BiTree T,int x,BitNode *&p) 45 { 46 47 p=NULL; 48 while(T!=NULL&&x!=T->data) 49 { 50 p=T; 51 if(x<T->data) 52 T=T->lchild; 53 else T=T->rchild; 54 } 55 return T; 56 } 57 /*结点的删除*/ 58 /* 59 1、如果是叶结点,直接删除即可 60 2、如果删除的结点只有单枝左子树或者右子树→让子树成为父结点的子树,直接替代被删结点的位置 61 3、如果删除的结点有左右两棵子树,这里可以采用p的(x序遍历)直接后继或者直接前驱进行替代。 62 这里选为中序遍历的直接后继作为替代结点,其中序遍历下的直接后继为被删除结点右子树最左结点。 63 4、在最后链接被删结点双亲和被删结点孩子的这一步中,如果被删结点为根结点,则不需修改它双亲结点(本来就没双亲),但是要修改指向树的指针T!!不然它会指向空域。 64 */ 65 int relationship(BitNode *a,BitNode *b) 66 { 67 if(a->lchild==b) return 1;//b是a的左孩子 68 else if(a->rchild==b) return 2;//b是a的右孩子 69 else return 3;//没关系 70 } 71 72 int Delete(BiTree &T,int x) 73 { 74 BitNode *p=NULL,*psdad=NULL; 75 BitNode *tool=NULL,*tooldad=NULL; 76 p=BST_Search(T,x,psdad); 77 //如果删除的结点是叶结点 78 if(p->lchild==NULL&&p->rchild==NULL) 79 { 80 if(relationship(psdad,p)==1) 81 { 82 psdad->lchild=NULL; 83 } 84 else 85 { 86 psdad->rchild=NULL; 87 } 88 free(p); 89 } 90 else if(p->lchild==NULL) 91 { 92 if(relationship(psdad,p)==1) 93 { 94 psdad->lchild=p->rchild; 95 free(p); 96 } 97 else 98 { 99 psdad->rchild=p->rchild; 100 free(p); 101 } 102 } 103 else if(p->rchild==NULL) 104 { 105 if(relationship(psdad,p)==1) 106 { 107 psdad->lchild=p->lchild; 108 free(p); 109 } 110 else 111 { 112 psdad->rchild=p->lchild; 113 free(p); 114 } 115 } 116 else//p有左右两棵子树//有错,明天思考 117 { 118 tooldad=p; 119 tool=p->rchild; 120 /*转向右子树,向左走到尽头*/ 121 //cout<<"tool1:"<<tool->data<<endl; 122 //if(tooldad!=NULL) 123 // cout<<"tooldad:"<<tooldad->data<<endl; 124 //else cout<<"tooldad:null"<<endl; 125 126 while(tool->lchild) 127 { 128 tooldad=tool; 129 tool=tool->lchild; 130 } 131 132 //cout<<"tool2:"<<tool->data<<endl; 133 //if(tooldad!=NULL) 134 // cout<<"tooldad:"<<tooldad->data<<endl; 135 //else cout<<"tooldad:null"<<endl; 136 if(tool==p->rchild)//即:被删除结点右子树的中序遍历第一个结点就是右孩子,这时直接把右孩子挪上去代替被删结点 137 { 138 //cout<<"ct1"<<endl; 139 tool->lchild=p->lchild; 140 if(psdad)//如果被删除的不是根结点 则需要把代替原位置的结点和被删结点的双亲接连上去 141 { 142 if(relationship(psdad,p)==1) 143 { 144 psdad->lchild=tool; 145 free(p); 146 } 147 else 148 { 149 psdad->rchild=tool; 150 free(p); 151 } 152 } 153 else//被删除的是根结点 要把指向根结点的指针一并修改 不然树头会指向空域 154 {T=tool;free(p);} 155 } 156 else 157 { 158 //cout<<"ct2"<<endl; 159 tooldad->lchild=tool->rchild;//当前结点为最左结点,它一定没有左孩子,可能有右孩子。 160 tool->lchild=p->lchild; 161 tool->rchild=p->rchild; 162 tool->lchild=p->lchild; 163 if(psdad) 164 { 165 if(relationship(psdad,p)==1) 166 { 167 psdad->lchild=tool; 168 free(p); 169 } 170 else 171 { 172 psdad->rchild=tool; 173 free(p); 174 } 175 } 176 else {T=tool;free(p);} 177 } 178 } 179 return OK; 180 181 } 182 183 void visit(BiTree T) 184 { 185 cout<<T->data<<' '; 186 } 187 /*中序遍历测试用*/ 188 void inOrder(BiTree T) 189 { 190 if(T!=NULL) 191 { 192 inOrder(T->lchild); 193 visit(T); 194 inOrder(T->rchild); 195 } 196 } 197 int main() 198 { 199 BiTree tree=NULL; 200 BitNode *ans=NULL,*ansdad=NULL; 201 int x; 202 cin>>x; 203 while(x!=0) 204 { 205 initTree(tree,x); 206 cin>>x; 207 } 208 cout<<"--- show the bst tree ---"<<endl; 209 inOrder(tree); 210 cout<<endl; 211 cout<<"Test Search function:"<<endl; 212 cin>>x; 213 ans=BST_Search(tree,x,ansdad); 214 if(ans==NULL) 215 cout<<"NULL."<<endl; 216 else 217 { 218 cout<<"successful found."<<ans->data<<endl; 219 if(ansdad!=NULL) 220 cout<<"His father's data is:"<<ansdad->data<<endl; 221 else cout<<"He is the Root of BST tree."<<endl; 222 } 223 int w; 224 225 cin>>w; 226 while(w!=0) 227 { 228 Delete(tree,w); 229 cout<<"--- show the bst tree ---"<<endl; 230 inOrder(tree); 231 cout<<endl; 232 cin>>w; 233 } 234 return 0; 235 }
5、代码实现截图