二叉排序樹(Binary Sort Tree)

來源:互聯網
上載者:User

標籤:style   blog   http   color   資料   2014   

二叉排序樹(Binary Sort Tree)又稱二叉尋找樹,是一種排序和尋找都很有用的特殊二叉樹。
BST 滿足 左節點的值<根節點的值<右節點的值。根據這個原理,我們可以推斷:BST的中序遍曆必定是嚴格遞增的。

一棵二叉樹,是一棵BST。我們可以明顯看到他的中序遍曆為09,17,23,45,53,60,70,75,78,88,94。(因為左<中<右)

下面是BST的實現,包括BST的插入,建立,刪除,遍曆

//BST.h#include<iostream>using namespace std;template<typename T>struct node{    T key;    //char word;};template<typename T>struct BSTNode{    node<T> data;    BSTNode<T> *lchild;    BSTNode<T> *rchild;};template<typename T>class BSTree{private:    BSTNode<T> *bt;//根指標public:    BSTree();//建構函式    ~BSTree();//解構函式    BSTNode<T>* & GetRoot();//得到跟節點    void Clear(BSTNode<T>* &p);//刪除節點,釋放空間    bool BSTInsert(BSTNode<T>* &p,T key);//在p指向的二叉樹中有序插入 資料元素為key的節點    void Create(int n);//建立含有n個元素的BST    void PreTraBST(BSTNode<T> *p);//前序走訪    void InTraBST(BSTNode<T> *p);//中序遍曆,輸出的BST是從小到大排列的    void SearchBST(BSTNode<T> *p,T key);//在p指向的二叉樹中尋找 是否存在資料元素key    int Delete(BSTNode<T> * &p);//刪除節點p    int DeleteBST(BSTNode<T>* &p,T key);//在p指向的BST中刪除資料元素key,並保證刪除後的二叉樹還是BST};template<typename T>BSTree<T>::BSTree(){    bt=NULL;}template<typename T>BSTree<T>::~BSTree(){    BSTNode<T> *p;    p=bt;    Clear(p);}template<typename T>BSTNode<T>* & BSTree<T>::GetRoot(){    return bt;}template<typename T>void BSTree<T>::Clear(BSTNode<T> * &p){    if(p)    {        Clear(p->lchild);        Clear(p->rchild);    }    getchar();    delete p;    cout<<"刪除節點"<<p<<"的空間"<<endl;}template<typename T>bool BSTree<T>::BSTInsert(BSTNode<T>* &p,T key)//在p指向的二叉樹中有序插入資料元素key{    if(p==NULL) //p為空白樹,建立資料元素為key的新節點,並將p指向該節點    {        BSTNode<T> *s=new BSTNode<T>;        s->data.key=key;        s->lchild=s->rchild=NULL;        p=s;        return true;    }    else if(key>p->data.key)//key 大於節點p->data.key,遞迴遍曆右子樹。BST的右子樹一定大於左子樹        BSTInsert(p->rchild,key);    else if(key<p->data.key)//key 小於節點p->data.key,遍曆左子樹。        BSTInsert(p->lchild,key);    else if(key==p->data.key)    {        cout<<"插入資料已存在"<<endl;        return false;    }}template<typename T>void BSTree<T>::Create(int n){    T key;    bt=NULL;     cout<<"輸入"<<n<<"個不同的資料元素"<<endl;    for(int i=0;i<n;i++)    {        cin>>key;        BSTInsert(bt,key);    }}template<typename T>void BSTree<T>::PreTraBST(BSTNode<T> *p){    if(p)    {        cout<<p->data.key<<" ";        PreTraBST(p->lchild);        PreTraBST(p->rchild);    }}template<typename T>void BSTree<T>::InTraBST(BSTNode<T> *p) //中序輸出時資料元素一定是按升序排列的{    if(p)    {        InTraBST(p->lchild);        cout<<p->data.key<<" ";        InTraBST(p->rchild);    }}template<typename T>void BSTree<T>::SearchBST(BSTNode<T> *p,T key)//在BST中尋找資料元素key 是否存在,存在則找出其中的p,並且刪除{    if(p==NULL||p->data.key==key)    {        if(p==NULL)        {            cout<<"尋找的資料元素不存在"<<endl;        }        else if(p->data.key==key)        {            cout<<"找到資料元素"<<key<<endl;        }    }    else if(key>p->data.key)    {        SearchBST(p->rchild,key);    }    else if(key<p->data.key)    {        SearchBST(p->lchild,key);    }        }template<typename T>int BSTree<T>::Delete(BSTNode<T>* &p)//刪除節點p{    BSTNode<T> *q,*s;    if(p->rchild==NULL)//待刪除的節點p沒有右子樹    {        q=p;        p=p->lchild;        cout<<"成功刪除"<<endl;        delete q;            }    else if(p->lchild==NULL)//待刪除的節點p沒有左子樹    {        q=p;        p=p->rchild;        cout<<"成功刪除"<<q->data.key<<endl;        delete q;            }    else if(p->lchild==NULL&&p->rchild==NULL)    {                delete p;        cout<<"成功刪除"<<endl;    }    else//待刪除的節點p的左右節點都存在    {        q=p;        s=p->lchild;        while(s->rchild)//在p節點的左子樹中尋找其前驅節點。即最右節點。        {            q=s;            s=s->rchild;//最終s指向待刪除節點的前驅節點        }        p->data=s->data;//將前驅節點賦值給p節點        if(q!=p)            q->rchild=s->lchild;        else q->lchild=s->lchild;        delete s;        cout<<"成功刪除"<<endl;        }    return true;}template<typename T>int BSTree<T>::DeleteBST(BSTNode<T>* &p,T key){    if(p==NULL)    {        cout<<"二叉樹為空白,無法刪除"<<endl;        return false;    }    else    {        if(key==p->data.key)            return Delete(p);        else if(key>p->data.key)            return DeleteBST(p->rchild,key);        else            return DeleteBST(p->lchild,key);    }}
//BST-main.cpp#include<iostream>using namespace std;#include"BST.h"int main(void){    int n,key,flag;    BSTree<int> bst;    cout<<"輸入二叉樹的資料元素個數:";    cin>>n;    bst.Create(n);//Create建立的是一個排序二叉樹    cout<<"先序遍曆輸出:";    bst.PreTraBST(bst.GetRoot());    cout<<endl;    cout<<"中序遍曆輸出:";//中序遍曆一定是有序的    bst.InTraBST(bst.GetRoot());    cout<<endl;    cout<<"輸入要尋找的元素:";    cin>>key;    bst.SearchBST(bst.GetRoot(),key);    flag=1;    while(flag)    {        cout<<"輸入要刪除的元素(-1為結束標誌):";        cin>>key;        if(key!=-1)        {            bst.DeleteBST(bst.GetRoot(),key);        }        else            flag=0;        cout<<"先序遍曆輸出:";        bst.PreTraBST(bst.GetRoot());        cout<<endl;        cout<<"中序遍曆輸出:";//中序遍曆一定是有序的        bst.InTraBST(bst.GetRoot());        cout<<endl;    }    getchar();}

測試結果如下:

關於BST 刪除資料元素的理解

1.待刪除的節點p沒有右子樹  p->rchild==NULL

2.待刪除的節點p沒有左子樹 p->lchild==NULL

3.左右子節點都不存在  p->lchild==NULL&&p->rchild==NULL

直接刪除

 

4.左右子節點都存在   p->lchild!=NULL&&p->rchild!=NULL

4.1   q!=p  其中s指向待刪除節點的前驅節點,然後用77替換78,並將75指向76

      

4.2  p==q  將節點70賦值給節點80

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.