标签:
对《大话数据结构》P313~P340—二叉排序树和平衡二叉树,进行了自己的理解并完善了代码。
一、二叉排序树
对如下二叉排序树进行中序遍历,就可以得到有序的序列{35,37,47,51,58,62,73,88,93,99}。
查找:
插入:
删除:
1、删除的是叶子节点
2、删除的结点仅有左孩子或右孩子
3、删除的结点既有左孩子也有右孩子
代码和解释如下(VS2012测试通过):
1 #include <iostream> 2 using namespace std; 3 #define TRUE 1 4 #define FALSE 0 5 typedef int Status; 6 7 //二叉树的二叉链表结点结构定义 8 typedef struct BiTNode 9 { 10 int data; 11 struct BiTNode *lchild, *rchild; 12 } BiTNode; 13 14 //二叉排序树的查找操作 15 //递归查找二叉排序树中是否存在key 16 //指针f指向T的双亲,初始调用值为NULL 17 //若查找成功,指针P指向该数据元素结点,并返回TRUE 18 //否则指针P指向查找路径上访问的最后一个结点,并返回FALSE,这个P指向的结点对插入很有用 19 Status SearchBST(BiTNode *T,int key,BiTNode *f,BiTNode **p) 20 { 21 if(!T)//查找不成功 22 { 23 *p=f; 24 return FALSE; 25 } 26 else if(key==T->data)//查找成功 27 { 28 *p=T; 29 return TRUE; 30 } 31 else if(key<T->data) 32 return SearchBST(T->lchild,key,T,p);//在左子树继续查找 33 else 34 return SearchBST(T->rchild,key,T,p);//在右子树继续查找 35 } 36 37 //二叉排序树的插入操作 38 //当二叉排序树T中不存在关键字等于key的数据元素时,插入key并返回TRUE,否则返回FALSE 39 Status InsertBST(BiTNode **T,int key) 40 { 41 BiTNode *p,*s; 42 if(!SearchBST(*T,key,NULL,&p))//如果二叉排序树中不存在key 43 { 44 s=new BiTNode; 45 s->data=key; 46 s->lchild=s->rchild=NULL; 47 if(!p)//说明原本是一棵空树 48 *T=s;//插入s为新的根节点 49 else if(key<p->data) 50 p->lchild=s;//左子树的结点值小于根的值 51 else 52 p->rchild=s;//右子树的结点值大于根的值 53 return TRUE; 54 } 55 else 56 return FALSE;//SearchBST返回TRUE,二叉排序树中已存在key,不再插入 57 } 58 59 //从二叉排序树中删除结点p,并重接它的左或右子树 60 Status Delete(BiTNode **p) 61 { 62 BiTNode *q,*s; 63 if((*p)->rchild==NULL)//*p指向的待删除节点的右子树空,则只需将*p指向它的左子树,再将*p指向的结点删除 64 { 65 q=*p; *p=(*p)->lchild; free(q);//先把*p暂存在q,*p指向左子树,再把q释放即可 66 } 67 else if((*p)->lchild==NULL)//*p指向的待删除节点的左子树空 68 { 69 q=*p; *p=(*p)->rchild; free(q); 70 } 71 else //左右子树均不空,通过找*p指向的待删除节点的前驱和后继,用前驱或后继的值替换待删除节点的值,注意不是删除,是替换值 72 { 73 q=*p; s=(*p)->lchild; 74 while(s->rchild) //找左子树的右子树尽头,找待删结点的前驱 75 { 76 q=s; 77 s=s->rchild; 78 } 79 (*p)->data=s->data;//s指向被删结点的直接前驱,用将被删结点的前驱的值取代被删结点的值 80 if(q!=*p) 81 q->rchild=s->lchild;//重接q的右子树 82 else 83 q->lchild=s->lchild;//重接q的左子树 84 free(s); 85 } 86 return TRUE; 87 } 88 89 //若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点,并返回TRUE,否则返回FALSE 90 Status DeleteBST(BiTNode **T,int key) 91 { 92 if(!*T)//不存在关键字等于key的数据元素 93 return FALSE; 94 else 95 { 96 if (key==(*T)->data)//找到关键字等于key的数据元素,调用delete函数 97 return Delete(T); 98 else if (key<(*T)->data) 99 return DeleteBST(&(*T)->lchild,key);//递归,从左子树找key 100 else 101 return DeleteBST(&(*T)->rchild,key);//递归,从右子树找key 102 } 103 } 104 105 int main() 106 { 107 int i; 108 int a[10]={62,88,58,47,35,73,51,99,37,93}; 109 BiTNode *T=NULL; 110 for(i=0;i<10;i++) 111 { 112 InsertBST(&T, a[i]); 113 } 114 DeleteBST(&T,47); 115 }
二叉排序树已链接的方式存储,插入删除的时间性能比较好。只要找到合适的插入和删除位置后,修改链接指针即可。但对于二叉排序树的查找,从根节点到要查找的结点,比较次数等于给定值的结点在二叉排序树的层数,即查找性能取决于二叉排序树的形状。有可能深度与完全二叉树相同,为log2n+1,查找复杂度就是O(logn),也有可能是斜树,查找复杂度为O(n)。所以我们需要要让二叉排序树平衡。
二、平衡二叉树(AVL树)
标签:
原文地址:http://www.cnblogs.com/hslzju/p/5439388.html