码迷,mamicode.com
首页 > 其他好文 > 详细

二叉查找树(插入、查找、遍历、删除.........)

时间:2015-07-07 22:58:11      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:二叉查找树

【二叉查找树的性质】

 二叉查找树是满足以下条件的二叉树:

  1. 左子树上的所有节点值均小于根节点值
  2. 右子树上的所有节点值均不小于根节点值
  3. 左右子树也都是二叉查找树
  4. 不存在两个节点的值相等

【二叉查找树的插入、删除过程】

二叉查找树的插入过程如下:
1. 若当前的二叉查找树为空,则插入的元素为根节点
2. 若插入的元素值小于根节点值,则将元素插入到左子树中;若插入的元素值不小于根节点值,则将元素插入到右子树中。

二叉查找树的删除,分三种情况进行处理:
1. p为叶子节点,直接删除该节点,再修改其父节点的指针(注意分是根节点和不是根节点)
2. p为单支节点(即只有左子树或右子树)。让p的子树与p的父亲节点相连,删除p即可;(注意分是根节点和不是根节点)
3. p的左子树和右子树均不空。找到p的前驱s,s一定没有右子树,所以可以删除s,用s的值代替p的值,让s的父亲节点t成为s的左子树的父亲节点。

【代码实现】

//binarysearch.h代码
#ifndef binarysearch_h
#define binarysearch_h
template<class T> class BST;
template<class T>
class BSTnode
{
    friend class BST<T>;
private:
  T data;
  BSTnode<T> *lchild;
  BSTnode<T> *rchild;
};
template<class T>
class BST
{
public:
    BST()
    {
     root=0;
    } 

    void Insert(T item); //插入操作

    void display();
    void display(BSTnode<T> *currentnode,int i);//输出元素的位置

    BSTnode<T> *Search(T item);
    BSTnode<T> *Search(BSTnode<T> *currentnode,T item);//递归查找

    BSTnode<T> *Search2(T item);//迭代查找

    void Inorder();
    void Inorder(BSTnode<T> *currentnode);//中序遍历

    void delete_BST(T x);//删除操作
private:
    BSTnode<T> *root;
};

//-------实现元素的按序插入-----------
template<class T>
void BST<T>::Insert(T item)
{
  BSTnode<T> *p=root;
  BSTnode<T> *q=0;  //q为p的父节点
  while(p)
  {
   q=p;
   if(item<p->data)
   {
     p=p->lchild;
   }
   else if(item>p->data)
   {
     p=p->rchild;
    }
   else
   {
      // cout<<"不能重复插入"<<item<<endl;
       return;
   }
  }
  //找到插入位置q
  p=new BSTnode<T>();
  p->lchild=p->rchild=0;
  p->data=item;
  if(!root)  //当为空树时
  {
   root=p;
  }
  else if(item<q->data)//作为q的左孩子
  {
   q->lchild=p;
  }
  else
  {
   q->rchild=p;//作为q的右孩子
  }
}

//--------输出每个元素的位置---------
template<class T>
void BST<T>::display()
{
  if(root)
     display(root,1);
   else
     cout<<"这是一棵空树!"<<endl;
} 
template<class T>
void BST<T>::display(BSTnode<T> *currentnode,int i)
{
    cout<<"position "<<i<<":"<<currentnode->data<<endl;
    if(currentnode->lchild)
      display(currentnode->lchild,2*i);
    if(currentnode->rchild)
      display(currentnode->rchild,2*i+1);
}

//------二叉查找树的递归查找-----------
template<class T>
BSTnode<T>* BST<T>::Search(T item)
{
    return Search(root,item);
}
template<class T>
BSTnode<T>* BST<T>::Search(BSTnode<T> *currentnode,T item)
{
  if(!currentnode)
  {
   return 0;  //没找到,返回空指针
  }
  if(currentnode->data==item) 
      return currentnode;
  else if(currentnode->data>item) 
      return Search(currentnode->lchild,item);
  else
      return Search(currentnode->rchild,item);

}

//------二叉查找树的迭代查找-----------
template<class T>
BSTnode<T>* BST<T>::Search2(T item)
{
    BSTnode<T>*p=root;
    while(p)
    {
      if(p->data==item)
          return p;
      else if(p->data>item)
          p=p->lchild;
      else
         p=p->lchild;
    }
   return 0;
}


//--------递归实现中序遍历---------
template<class T>
void BST<T>::Inorder()
{
  cout<<"中序遍历为:";
  Inorder(root);
  cout<<endl;
}
template<class T>
void BST<T>::Inorder(BSTnode<T> *currentnode)
{
  if(currentnode)
  {
   Inorder(currentnode->lchild);
   cout<<currentnode->data<<" ";
   Inorder(currentnode->rchild);
  }
}


//-------------删除元素--------------
template<class T>
void BST<T>::delete_BST(T x) 
{
    BSTnode<T> * p,*q;
    p=root; 
    //寻找被删元素 
    while(p)
    { 
        if(x==p->data)//找到被删元素 
        {  
           break;    
        }    
        else if(x<p->data)//沿左子树找 
        { 
            q = p;        //q记录p的父节点
            p = p->lchild;    
        }
        else           //沿右子树找 
        {  
            q = p;    //q记录p的父节点
            p = p->rchild;    
        }
    }
    if(!p)    //没找到 
    {   
        cout << "没有找到" << x << endl;    
    }
    //p为待删除节点
    if(p->lchild == 0 && p->rchild == 0) //情况1:p为叶子节点 
    {  
        if(p == root) //p为根节点 
        { 
           root = 0;    
        }
        else if(q->lchild == p)//p为左子树
        {   
            q->lchild =0;
        }        
        else  //p为右子树
        {
            q->rchild =0;    
        }
       delete(p);  //释放节点p 
    }
    else if(p->lchild ==0 || p->rchild == 0)  //情况2:p为单支子树
    {  
        if(p == root) //p为根节点 
        {  
            if(p->lchild ==0)
            {
               root = p->rchild;    
            }    
            else
            {
                root = p->lchild;    
            }
        }    
        else
        {
            if(q->lchild == p && p->lchild) //p是q的左子树且p有左子树 
            { 
                q->lchild = p->lchild;    //将p的左子树链接到q的左指针上 
            }    
            else if(q->lchild == p && p->rchild) //p是q的左子树且p有右子树
            {
                q->lchild = p->rchild;    //将p的右子树链接到q的左指针上 
            }
            else if(q->rchild == p && p->lchild)//p是q的右子树且p有左子树
            {
                q->rchild = p->lchild;   //将p的左子树链接到q的右指针上 
            }
            else                        //p是q的右子树且p有右子树
            {
                q->rchild = p->rchild;//将p的右子树链接到q的右指针上 
            }
        }
        delete(p);
    }
    else                           //情况3:p的左右子树均不为空 
    { 
        BSTnode<T> *t,*s;
        t=p;
        s = p->lchild;  //从p的左子节点开始 
        while(s->rchild) //找到p的前驱s(s一定没有右子树),即p左子树中值最大的节点 
        {  
            t = s;     //t记录s的父节点
            s = s->rchild;    
        }
        p->data = s->data;   //把节点s的值赋给p 
        if(t == p)
        {
            t->lchild = s->lchild;    
        }    
        else   
        {
            t->rchild = s->lchild;    //将p的前驱s的父节点指向s的左子树
        }
        delete(s); 
    }
}
#endif
//main.cpp
#include"binarysearch.h"
#include <iostream>
using namespace std;
int main()
{
  BST<int> B1;
  B1.Insert(5);
  B1.Insert(3);
  B1.Insert(11);
  B1.Insert(8);
  B1.Insert(3);
  B1.display(); 
  B1.Inorder();
 // BSTnode<int> *p=B1.Search(3);
  BSTnode<int> *p=B1.Search2(3);
  if(p)
    cout<<"找到3!"<<endl;
  cout<<"删除5后:"<<endl;
  B1.delete_BST(5);
  B1.display(); 
  B1.Inorder();
  system("pause");
  return 0;
}

【程序结果】

技术分享

版权声明:本文为博主原创文章,未经博主允许不得转载。

二叉查找树(插入、查找、遍历、删除.........)

标签:二叉查找树

原文地址:http://blog.csdn.net/adminabcd/article/details/46792905

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!