二叉搜索树的根插入选择删除合并排序等操作的实现
Posted gavanwanggw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉搜索树的根插入选择删除合并排序等操作的实现相关的知识,希望对你有一定的参考价值。
源码例如以下:
这里的Key 不当为keyword对待。 而是把Item.c作为keyword对待
#include <stdlib.h> #include <stdio.h> //#define Key int typedef int Key; struct Item{ Key key; char c; }; typedef struct STnode* link; struct STnode{ Item item ; link l,r; int N; }; static link head , z ; static struct Item NULLitem ; Key key(Item item){ return item.key; } //创建一个节点 link NEW(Item item, link l,link r, int N){ link x = (link)malloc(sizeof *x); x->item = item;x->l = l;x->r = r;x->N = N; if(head==z)head=x; //这句话不能少!!! return x; } //初始化 void STinit(){ head = ( z = NEW(NULLitem,0,0,0)); } //节点个数 int STcount(){ return head->N; } //搜索子程序 Item searchR(link h, char v){ char t = h->item.c; if(h==z)return NULLitem; if(v==t) return h->item; if(v<t) return searchR(h->l,v); else return searchR(h->r,v); } //搜索主程序 Item STsearch(Key v){ return searchR(head,v); } //选择第K小关键值的项 K从0開始 Item selectR(link h, int k) { int t; if(h==z)return NULLitem; t = (h->l==z)?0:h->l->N; if(t>k) return selectR(h->l,k); if(t<k) return selectR(h->r,k-t-1); return h->item; } Item STselect(int k){ return selectR(head,k); } //----------------根插入--------------------// //右旋转 顺时针旋转 link rotR(link h){ link x = h->l; h->l = x->r; x->r=h; } //左旋转 逆时针旋转 link rotL(link h){ link x = h->r; h->r = x->l; x->l=h; } //插入子程序 link insertT(link h, Item item){ // Key v = key(item), t = key(h->item); char v = item.c, t = h->item.c; if(h==z)return NEW(item,z,z,1); if(v<t) {h->l = insertT(h->l,item); h = rotR(h); } else {h->r = insertT(h->r,item); h = rotL(h);} (h->N)++;return h; } //BST根插入主程序 void STinsert(Item item){ //新插入的节点都会当作根节点 head = insertT(head,item); } //----------------根插入--------------------// //----------------删除一个节点----方法1-----乾坤大挪移-----------// link partR(link h, int k) { int t = h->l->N; //为什么没有推断非空? if(t>k){h->l = partR(h->l,k);h=rotR(h);} if(t<k){h->r = partR(h->r,k-t-1);h=rotL(h);} return h; } link joinLR(link a ,link b){ if(b==z)return a; b=partR(b,0); b->l = a; return b; } link delR(link h, char k){ link x; char t = h->item.c; if(h==z)return z; if(t>k)h->l=delR(h->l,k); if(t<k)h->r=delR(h->r,k); if(t==k){ x = h;h=joinLR(h->l,h->r);free(x); } return h; } //删除主程序 void STdelete(char v){ head = delR(head,v); } //----------------删除一个节点-----方法1-----乾坤大挪移----------// //----------------删除一个节点-----方法2---------------// //删除子程序 Item deleteR(link F){ Item tmp; link p; if(F->l==NULL){ p = F; tmp = F->item; F = F->r; free(p); return tmp; }else return deleteR(F->l); } //删除子程序 void deleteRR(link h , Key v){ if(h!=NULL){ Key t = key(h->item); if(v<t) deleteRR(h->l,v); else if(v>t) deleteRR(h->r,v); else if(h->l==NULL) { //处理仅仅有一颗子树或没有子树的情况 1 link p = h->r; h=p; free(p); } else if(h->r==NULL){ //处理仅仅有一颗子树或没有子树的情况 2 link p = h->l; h=p; free(p); } else h->item= deleteR(h->r); //假设待删除的节点既有左子树又有右子树 //则用该节点右子树的最左下节点替换之,维持二叉搜索树 } } //删除主程序 void STdelete2(Key v){ deleteRR(head,v); } //----------------删除一个节点-----方法2---------------// void sortR(link h){ if(h==z)return; sortR(h->l); if(h->item.key!=0) printf("%c ",h->item.c); sortR(h->r); } //二叉搜索树排序 void STsort(link h){ sortR(h); } //接连两颗二叉搜索树 link STjoin(link a ,link b){ if(b==z)return a; if(a==z)return b; b = insertT(b,a->item); b->l = STjoin(a->l,b->l); b->r=STjoin(a->r,b->r); free(a); return b; } void test(){ struct Item item1 = {322,‘a‘}; struct Item item2 = {23,‘s‘}; struct Item item3 = {2,‘e‘}; struct Item item4 = {332,‘r‘}; struct Item item5 = {332,‘c‘}; struct Item item6 = {332,‘h‘}; struct Item item7 = {112,‘i‘}; STinit(); STinsert(item1);STinsert(item2); STinsert(item3);STinsert(item4); STinsert(item5);STinsert(item6); STinsert(item7); STsort(head); printf("\n"); struct Item item11 = STselect(2); printf("%c\n",item11.c); STdelete(‘i‘); STsort(head); } main(){ test(); }
以上是关于二叉搜索树的根插入选择删除合并排序等操作的实现的主要内容,如果未能解决你的问题,请参考以下文章
C++-二叉搜索树的查找&插入&删除-二叉搜索树代码实现-二叉搜索树性能分析及解决方案