C++資料結構 17 二叉查詢樹
阿新 • • 發佈:2018-11-24
Bst(Binary Search Tree)
有以下性質:
-
每一個元素有一個鍵值,而且不予許重複
-
左子樹的鍵值都小於根節點的鍵值
-
右子樹的鍵值都大於根節點的鍵值
-
左右子樹都是二叉查詢樹
程式碼:
#ifndef __BST_H__ #define __BST_H__ #include<iostream> using namespace std; template <class T> class Bst; //宣告 enum Boolean {False,True}; template<class T> class Element //資料 { public: T Key; //定義鍵值 }; template<class T> class BstNode //定義結點 { friend class Bst<T>; public: Element<T> data; //結點資料 BstNode *LeftChild; //左孩子 BstNode *RightChild;//右孩子 void display(int i); //顯示 }; template<class T> class Bst //定義二叉查詢樹 { public: Bst(BstNode<T>*init=0) //定義建構函式 { root=init; } Boolean Insert(Element<T>&x); //插入元素 BstNode<T>* Search(const Element<T>&x); //遞迴查詢 BstNode<T>* Search(BstNode<T>*p,const Element<T>&x); BstNode<T>* ItearSearch(const Element<T>&x); //採用迭代方式查詢 void display() { cout<<endl; if(root) root->display(1); //根從1開始顯示 } void Preorder(BstNode<T> *CurrentNode); //前序遍歷 void Inorder(BstNode<T> *CurrentNode); //中序遍歷 void Postorder(BstNode<T> *CurrentNode);//後序遍歷 void Vivit(BstNode<T> *CurrentNode); //當前節點 //private: BstNode<T>*root; //根結點 }; template<class T> void BstNode<T>::display(int i) //顯示資料 { cout<<"Position: "<<i<<" Data:"<<data.Key<<endl; //顯示位置和資料 if(LeftChild) LeftChild->display(2*i); //顯示左孩子 if(RightChild) RightChild->display(2*i+1); //顯示右孩子 } template<class T> Boolean Bst<T>::Insert(Element<T>&x) //插入資料 { //插入資料之前需要查詢資料 BstNode<T> *p=root; //初始指向根節點 BstNode<T> *q=0; //用來儲存上一個父節點 while(p) { q=p; //儲存上一個父節點 if(x.Key==p->data.Key) return False; //如果節點存在 則返回錯誤 if(x.Key>p->data.Key) p=p->RightChild; //如果節點父節點大,則放到右節點 else p=p->LeftChild; //否則,放到左節點 } //找到的位置就是q p=new BstNode<T>; p->LeftChild=p->RightChild=0; //剛開始令左孩子和右孩子都等於0 p->data=x; if(!root) root=p; //如果根不存在 p就是根 else if(x.Key>q->data.Key) q->RightChild=p; //鍵值比父節點大,則放到右孩子 else q->LeftChild=p; //否則,放到左孩子 return True; //返回正確 } template<class T> BstNode<T>* Bst<T>::Search(const Element<T>&x) //查詢 { return Search(root,x); //從根開始查詢 } template<class T> BstNode<T>* Bst<T>::Search(BstNode<T>*p,const Element<T>&x) { if(!p) return 0; //如果b不存在 返回0 if(x.Key==p->data.Key) return p; //找到了 返回p if(x.Key>p->data.Key) Search(p->RightChild,x); //比父節點大 從右開始找 else Search(p->LeftChild,x); //否則 從左開始找 } template<class T> BstNode<T>* Bst<T>::ItearSearch(const Element<T>&x)//採用迭代方式查詢 { BstNode<T>*p; for(p=root;p;) //p等於root p有效就一直查詢 { if(x.Key==p->data.Key) return p; if(x.Key>p->data.Key) p=p->RightChild; //如果大於則p指向下一個右孩子 else p=p->LeftChild; //否則 指向左孩子 } //迴圈結束都沒找到 return 0; // } static int cnt=0; //節點數 /*遍歷*/ template<class T> void Bst<T>::Vivit(BstNode<T> *CurrentNode) { cout<<CurrentNode->data.Key<<' '; //顯示當前資料鍵值 } template<class T> void Bst<T>::Preorder(BstNode<T> *CurrentNode)//前序遍歷 { if(CurrentNode) { Vivit(CurrentNode); Preorder(CurrentNode->LeftChild); //左子樹 Preorder(CurrentNode->RightChild); //右子樹 } } template<class T> void Bst<T>::Inorder(BstNode<T> *CurrentNode)//中序遍歷 { if(CurrentNode) { Preorder(CurrentNode->LeftChild); //左子樹 Vivit(CurrentNode); Preorder(CurrentNode->RightChild); //右子樹 } } template<class T> void Bst<T>::Postorder(BstNode<T> *CurrentNode)//後序遍歷 { if(CurrentNode) { Preorder(CurrentNode->LeftChild); //左子樹 Preorder(CurrentNode->RightChild); //右子樹 Vivit(CurrentNode); } } #endif // __BST_H__
main
#include <iostream> #include "BST.h" using namespace std; int main() { Bst<int> p; Element<int>a,b,c,d,e,f,g,h,i,l,k; a.Key=5; b.Key=3; c.Key=11; d.Key=3; e.Key=15; f.Key=2; g.Key=8; h.Key=22; i.Key=20; l.Key=9; cout<<p.Insert(a)<<endl; cout<<p.Insert(b)<<endl; cout<<p.Insert(c)<<endl; cout<<p.Insert(d)<<endl; cout<<p.Insert(e)<<endl; cout<<p.Insert(f)<<endl; cout<<p.Insert(g)<<endl; cout<<p.Insert(h)<<endl; cout<<p.Insert(i)<<endl; cout<<p.Insert(l)<<endl; p.display(); BstNode<int> *m=p.ItearSearch(i); cout<<m->data.Key<<endl; //cout << "Hello world!" << endl; cout<<"前序遍歷"<<endl; p.Preorder(p.root); return 0; }