動態查找表的一種理想數據結構。
二叉排序樹的定義是:二叉排序樹T是一棵樹,它或者是空,或者具備一下三條性質:
(1)、如果T的根節點的左子樹非空,其左子樹所有結點的值均小於T的根節點的值
(2)、如果T的根節點的右子樹非空,其右子樹所有結點的值均大於T的根節點的值
(3)、T的根結點的左右子樹均為二叉排序樹
下面是代碼:
文件"tree.h"
[cpp]
- #include<iostream>
- #include<stack>
- #include<queue>
- using namespace std;
-
- #define MAX_NODE_NUM 20 //樹結點最大值
- class Bin_Sort_Tree;
- //樹結點
- class BSTnode
- {
- int tag;//後序遍歷作為訪問標志
- int data;
- BSTnode *lchild;
- BSTnode *rchild;
- friend class Bin_Sort_Tree;
- };
-
- //二叉排序樹
- class Bin_Sort_Tree
- {
- public:
- int Get_data(BSTnode *p)
- {
- return p->data;
- }
-
- bool Search_BST(BSTnode *T,int a,BSTnode *&f,BSTnode *&p)
- {
- /*-----------------------------
- /在樹中查找值為a的結點,查找到
- /了,用p保存該結點地址,f指向
- /p的雙親結點
- /-----------------------------*/
- p=T;
- while(p)
- {
- if(p->data==a)
- return true;
- else if(p->data>a)
- {
- f=p;
- p=p->lchild;
- }
- else
- {
- f=p;
- p=p->rchild;
- }
- }
- return false;
- }
-
- //將值為a的結點插入樹中,若值已存在,就不插入
- void Insert_BST_1(BSTnode *&T,int a)
- {
- BSTnode *f=NULL;
- BSTnode *p=NULL;
- if(Search_BST(T,a,f,p))
- return; //樹中已有值相同結點,不插入
- else
- {
- BSTnode *s=new BSTnode;
- s->data=a;
- s->lchild=s->rchild=NULL;
- if(s->data>f->data)
- f->rchild=s;
- else
- f->lchild=s;
- }
- }
-
- void Insert_BST_2(BSTnode *&T,int a) //插入算法遞歸實現
- {
- if(!T)
- {
- cout<<"樹為空"<<endl;
- return;
- }
- if(T->data>a)
- {
- if(!T->lchild)
- {
- T->lchild=new BSTnode;
- T->lchild->data=a;
- T->lchild->lchild=NULL;
- T->lchild->rchild=NULL;
- return;
- }
- else
- Insert_BST_2(T->lchild,a);
- }
- if(T->data<a)
- {
- if(!T->rchild)
- {
- T->rchild=new BSTnode;
- T->rchild->data=a;
- T->rchild->lchild=NULL;
- T->rchild->rchild=NULL;
- return;
- }
- else
- Insert_BST_2(T->rchild,a);
- }
-
- }
-
- void Create_BSTree(BSTnode *&T) //建樹
- {
- cout<<"輸入二叉排序樹的元素,輸入-1代表結束輸入:";
- int num[MAX_NODE_NUM];
- int a,i=0;
- while(cin>>a && a!=-1)
- {
- num[i]=a;
- i++;
- }
-
- if(num[0]==-1)
- {
- cout<<"排序樹為空"<<endl;
- return;
- }
-
- int k=i;
- T=new BSTnode;
- T->data=num[0];
- T->lchild=T->rchild=NULL;
- for(i=1;i<k;i++)
- Insert_BST_1(T,num[i]);
- cout<<"____建樹完成____"<<endl;
- }
-
- void Delete_BST(BSTnode *&T,int a)//刪除結點值為a的結點
- {
- /*---------------------------------------------------------
- / 從樹中刪除一個節點後,要保證刪後的樹還是一棵二叉排序樹,
- / 刪除前,首先是在樹中查找是否有這個結點,用p指向該結點,
- / 用f指向p的雙親結點,這個結點在樹中的位置有下面四種情況:
- /
- / 1:如果p指向的結點是葉子結點,那麼直接將f指針的左子樹或者
- / 右子樹置空,然後刪除p結點即可。
- /
- / 2:如果p指向的結點是只有左子樹或右子樹,那麼只需要讓p結點
- / 原來在f中的位置(左子樹或右子樹)用p的子樹代替即可。
- /
- / 3:如果p所指向的結點是根節點,那麼直接將根節點置空
- /
- / 4:如果p所指向的結點左右子樹都非空,為了刪除p後原序列的順
- / 序不變,就需要在原序列中先找出p的直接前驅(或者直接後繼)
- / 結點用那個結點的值來代替p結點的值,然後再刪掉那個直接前
- / 驅(或者直接後繼)結點。
- / 在中序遍歷序列中找結點的直接前驅的方法是順著結點的左孩子
- / 的右鏈域開始,一直到結點右孩子為空為止。
- /---------------------------------------------------------*/
-
- BSTnode *f=NULL;
- BSTnode *p=NULL;
- BSTnode *q=NULL;
- BSTnode *s=NULL;
- if(Search_BST(T,a,f,p))
- {
- if(p->lchild && p->rchild)
- {
- q=p;
- s=p->lchild;
- while(s->rchild)
- {
- q=s;
- s=s->rchild;
- }
- p->data=s->data;
- //s指向要刪除結點的直接前驅,且s是一定沒有右子樹的
- if(q!=p)
- q->rchild=s->lchild;
- else
- q->lchild=s->lchild;//這種情況是,q的左子樹的右子樹為空時
- delete s;
- cout<<"結點刪除成功"<<endl;
- return ;
- }
- else
- {
- if(!p->lchild) //左子樹為空
- {
- q=p;
- p=p->rchild;
- }
- else //右子樹為空
- {
- q=p;
- p=p->lchild;
- }
- //下面將p所指向的子樹連接到f所指(被刪結點的雙親)的結點上
- if(!T) //被刪的結點為根節點
- T=p;
- else if(q==f->lchild)
- f->lchild=p;
- else
- f->rchild=p;
- delete q;
- cout<<"結點刪除成功"<<endl;
- return;
- }
- }
- else
- {
- cout<<"要刪除的結點不存在"<<endl;
- return ;
- }
- }
-
- //下面是二叉樹的四種遍歷方式,都是非遞歸方式實現
-
- void PreOrder_Traverse(BSTnode *T) //前序遍歷
- {
- stack<BSTnode *> s;
- BSTnode *p;
- p=T;
- while(p || !s.empty())
- {
- if(p)
- {
- cout<<p->data<<" ";
- s.push(p);
- p=p->lchild;
- }
- else
- {
- p=s.top();
- s.pop();
- p=p->rchild;
- }
- }
- }
-
- void InOrder_Traverse(BSTnode *T) //中序遍歷
- {
- stack<BSTnode *> s;
- BSTnode *p=T;
- while(p || !s.empty())
- {
- if(p)
- {
- s.push(p);
- p=p->lchild;
- }
- else
- {
- p=s.top();
- s.pop();
- cout<<p->data<<" ";
- p=p->rchild;
- }
- }
- }
-
- void PostOrder_Traverse(BSTnode *T) //後序遍歷
- {
- stack<BSTnode *> s;
- BSTnode *p=T;
- while(p || !s.empty())
- {
- if(p)
- {
- p->tag=0;
- s.push(p);
- p=p->lchild;
- }
- else
- {
- p=s.top();
- if(p->tag)
- {
- cout<<p->data<<" ";
- s.pop();
- p=NULL;
- }
- else
- {
- p->tag=1;
- p=p->rchild;
- }
- }
- }
- }
-
- void LevelOrder_Traverse(BSTnode *T) //層次遍歷
- {
- queue<BSTnode *> q;
- BSTnode *p=T;
- q.push(p);
- while(!q.empty())
- {
- p=q.front();
- q.pop();
- cout<<p->data<<" ";
- if(p->lchild)
- q.push(p->lchild);
- if(p->rchild)
- q.push(p->rchild);
- }
- }
- };