二叉搜尋樹(BST樹)
阿新 • • 發佈:2018-11-17
二叉搜尋樹
文章目錄
1,定義
二叉查詢樹(Binary Search Tree),又名二叉搜尋樹或二叉排序樹。可以是一顆空樹,或者是具有下列性質的二叉樹:
(1)若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
(2)若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
2,C++實現二叉樹的基本操作
#include<iostream> #include<queue> #include<stack> using namespace std; /*BST樹的結點型別*/ template <typename T> struct BSTNode { BSTNode(T data=T()):mdata(data),mleft(NULL),mright(NULL){}//T data=T():0的初始化 T mdata; BSTNode<T>*mleft; BSTNode<T>*mright; }; template<typename T> class BSTree { public: BSTree():mroot(NULL){} ~BSTree(){} /*向BST樹中插入資料: 過程為: 若b是空樹,則將val所指結點作為根結點插入,否則: 若val等於b的根結點的資料域之值,則返回,否則: 若val小於b的根結點的資料域之值,則把val所指結點插入到左子樹中,否則: 把val所指結點插入到右子樹中 */ void insert(const T&val) { if(mroot==NULL) { mroot=new BSTNode<T>(val); return; } BSTNode<T>*ppre=mroot; BSTNode<T>*pcur=mroot; while(pcur!=NULL) { ppre=pcur; if(val<pcur->mdata) { pcur=pcur->mleft; } else if(val>pcur->mdata) { pcur=pcur->mright; } else { return; } } if(val<ppre->mdata) { ppre->mleft=new BSTNode<T>(val); } else { ppre->mright=new BSTNode<T>(val); } } /*BST樹的結點刪除 在二叉排序樹刪去一個結點,分三種情況討論: 若*p結點為葉子結點,即PL(左子樹)和PR(右子樹)均為空樹。由於刪去葉子結點不破壞整棵樹的結構,則只需修改其雙親結點的指標即可。 若*p結點只有左子樹PL或右子樹PR,此時只要令PL或PR直接成為其雙親結點*f的左子樹或右子樹即可,作此修改也不破壞二叉排序樹的特性。 若*p結點的左子樹和右子樹均不空。在刪去*p之後,為保持其它元素之間的相對位置不變,可按中序遍歷保持有序進行調整,可以有兩種做法:其一是令*p的左子樹為*f的左子樹,*s為*f左子樹的最右下的結點,而*p的右子樹為*s的右子樹;其二是令*p的直接前驅(或直接後繼)替代*p,然後再從二叉排序樹中刪去它的直接前驅(或直接後繼)。在二叉排序樹上刪除一個結點的演算法如下: */ void remove(const T&val) { if(mroot==NULL) { return; } BSTNode<T>*ppre=NULL; BSTNode<T>*pcur=mroot; while(pcur!=NULL) { if(val<pcur->mdata) { ppre=pcur; pcur=pcur->mleft; } else if(val>pcur->mdata) { ppre=pcur; pcur=pcur->mright; } else { break; } } if(pcur==NULL) { return; } if(pcur->mleft!=NULL&&pcur->mright!=NULL) { ppre=pcur; BSTNode<T>*pdel=pcur->mleft; ppre=pcur; BSTNode<T>*pdel=pcur->mleft; while(pdel->mright!=NULL) { ppre=pcur; pdel=pdel->mright; } //pdel為待刪除的結點 pcur->mdata=pdel->mdata; pcur=pdel; } //開始刪除結點,記錄當前待刪除結點的自孩子 BSTNode<T>*pchild=NULL; if(pcur->mleft!=NULL) { pchild=pcur->mright; } else if(pcur->mright!=NULL) { pchild=pcur->mleft; } //pcur 開始刪除操作 if(ppre==NULL) { mroot=pchild; } else if(pcur->mdata<=ppre->mdata) { ppre->mleft=pchild; } else { ppre->mright=pchild; } delete pcur; } /*BST樹的查詢*/ bool query(const T&val) { BSTNode<T>*pcur=mroot; while(pcur!=NULL) { if(val<pcur->mdata) { pcur=pcur->mleft; } else if(val>pcur->mdta) { pcur=pcur->mright; } else { return true; } } return false; } /*層序遍歷*/ void level() { cout<<"層序遍歷為:"; queue<BSTNode<T>*>QUE; QUE.push(mroot); while(!QUE.empty()) { BSTNode<T>*pcur=QUE.front(); cout<<pcur->mdata<<" "; if(pcur->mleft!=NULL) { QUE.push(pcur->mleft); } if(pcur->mright!=NULL) { QUE.push(pcur->mright); } QUE.pop(); } cout<<endl; } /*前序遍歷*/ //遞迴實現 void preOrder() { preOrder(mroot); } //非遞迴實現 void preOrder1() { if(mroot==NULL) { return; } cout<<"前序遍歷為:"; stack<BSTNode<T>*>Stack; BSTNode*pcur=mroot; while(pcur!=NULL||!Stack.empty()) { while(pcur!=NULL) { cout<<pcur->mdata<<" "; Stack.push(pcur); pcur=pcur->mleft; } if(!Stack.empty()) { pcur=Stack.top(); Stack.pop() pcur=pcur->mright; } } cout<<endl; } /*中序遍歷*/ //遞迴實現 void inOrder() { inOrder(mroot); } //非遞迴實現 void inOrder1() { cout<<"中序遍歷為:"; if(mroot==NULL) { return; } stack<BSTNode<T>*>Stack1; BSTNode<T>*pcur=mroot->mleft; Stack1.push(mroot); while(pcur!=NULL||!Stack1.empty()) { while(pcur!=NULL) { Stack1.push(pcur); pcur=pcur->mleft; } pcur=Stack1.top(); Stack1.pop(); cout<<pcur->mdata<<" "; pcur=pcur->mright; } cout<<endl; } /*後序遍歷*/ //遞迴實現 void lastOrder() { lastOrder(mroot); } //非遞迴實現 void lastOrder1() { if(mroot==NULL) { return; } cout<<"後序遍歷為:"; stack<BSTNode<T>*>Stack2; BSTNode<T>*ppre=NULL; BSTNode<T>*pcur=mroot; while(pcur!=NULL||!Stack2.empty()) { while(pcur!=NULL) { Stack2.push(pcur); pcur=pcur->mleft; } pcur=Stack2.top(); if(pcur->mright==NULL||pcur->mright==ppre) { cout<pcur->mdata<<" "; ppre=pcur; Stack2.pop(); pcur=NULL; } else pcur=pcur->mright; } cout<<endl; } private: BSTNode<T>*mroot;//指向BST樹的根節點 void preOrder(BSTNode<T>*pnode) { if(pnode!=NULL) { cout<<pnode->mdata<<" "; preOrder(pnode->mleft); preOrder(pnode->mright); } } void inOrder(BSTNode<T>*pnode1) { if(pnode1!=NULL) { inOrder(pnode1->mleft); cout<<pnode1->mdata<<" "; inOrder(pnode1->mright); } } void lastOrder(BSTNode<T>*pnode2) { if(pnode2!=NULL) { lastOrder(pnode2->mleft); lastOrder(pnode2->mright); cout<node2->mdata<<" "; } } }
函式實現:
int main() { BSTree<int>tree; tree.insert(57); tree.insert(24); tree.insert(90); tree.insert(8); tree.insert(35); tree.insert(68); tree.insert(124); tree.insert(12); tree.insert(46); tree.insert(79); tree.insert(234); //tree.remove(35); tree.level(); tree.preOrder1(); tree.inOrder(); tree.lastOrder(); return 0; }
結果: