1. 程式人生 > >C++資料結構 17 二叉查詢樹

C++資料結構 17 二叉查詢樹

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;
}