码迷,mamicode.com
首页 > 编程语言 > 详细

二叉排序树

时间:2016-04-27 17:09:26      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

对《大话数据结构》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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!