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

【二叉查找树的性质】

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

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

【程序结果】

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

时间: 2024-11-18 13:57:14

二叉查找树(插入、查找、遍历、删除.........)的相关文章

Java实现二叉排序树的插入、查找、删除

import java.util.Random; /** * 二叉排序树(又称二叉查找树) * (1)可以是一颗空树 * (2)若左子树不空,则左子树上所有的结点的值均小于她的根节点的值 * (3)若右子树不空,则右子树上所有的结点的值均大于她的根节点的值 * (4)左.右子树也分别为二叉排序树 * * * 性能分析: * 查找性能: * 含有n个结点的二叉排序树的平均查找长度和树的形态有关, * (最坏情况)当先后插入的关键字有序时,构成的二叉排序树蜕变为单枝树.查找性能为O(n) * (最好

单链表的使用(插入,查找,删除,链表的倒置,删除相同结点)

typedef struct node//该结构体代表一个结点{ int data; //结点的数据域 struct node *next; //结点的指针域}lnode,*linklist; //定义一个结构体变量和指向结构体的指针//用头插法创建一个链表linklist create_begin(){ linklist head=(linklist)malloc(sizeof(lnode));//定义头结点并开辟空间 head->next=NULL; //为避免指针乱指,将头结点下一个指针赋

java实现数据结构-线性表-顺序表,实现插入,查找,删除,合并功能

package 顺序表; import java.util.ArrayList; import java.util.Scanner; public class OrderList { /** * @param args * @author 刘雁冰 * @2015-1-31 21:00 */ /* * (以下所谓"位置"不是从0开始的数组下标表示法,而是从1开始的表示法.) * (如12,13,14,15,16数据中,位置2上的数据即是13) * * 利用JAVA实现数据结构-线性表-顺

字符串的插入、删除、查找并删除、重新赋值、替换

#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { //nsstring父类   NSMutableString可变字符串子类 NSMutableString *mustr=[[NSMutableString alloc]init]; NSMutableString *mustr1=[NSMutableString stringWithFormat:@&qu

顺序栈的初始化,建立,插入,查找,删除。

--- 顺序栈:普通数组保存方式,栈顶(max-1)为满,栈底(-1)为空: //////////////////////////////////////////// //顺序栈的初始化,建立,插入,查找,删除.// //Author:Wang Yong // //Date: 2010.8.19 // //////////////////////////////////////////// #include <stdio.h> #include <stdlib.h> #define

手写BST插入查找删除

binary search\sort\find tree operations status InsertNode(Node* root, data x, Node* father) { if(root==NULL) { if(father==NULL) Tree empty; else { if(x<father->data) { father->left=new Node//inital left right NULL father->left->data=x; retu

BST二叉排序树的查找和删除的完整C代码

二叉排序树的查找算法 假定二叉排序树的根节点指针为root,给定的关键字值为key,则查找算法可描述为: 置初值:p = root : 如果 key = p -> data ,则查找成功,算法结束: 否则,如果key < p->data ,而且 p 的左子树非空,则将 p 的左子树根送 p ,转步骤 2 :否则,查找失败,算法结束: 否则,如果 key > p->data ,而且 p 的右子树非空,则将 p 的右子树根送 p ,转步骤 2 :否则,查找失败,算法结束. //B

二叉查找树中元素的删除操作

关于二叉查找树的建立,插入,遍历(记住二叉查找树的中序遍历是所有元素由大到小排序结果)等操作,博主“C小加”写的很详细了,我主要补充二叉树的删除操作.删除操作主要难在对左右子节点都非空的节点的删除操作,这里可以找到该节点右节点中的最小值,即右子节点中的最左子树.找到后和需要删除的节点交换data等数据,然后删除这个最小子节点.实现代码如下,只需对需要删除节点的右子节点遍历一次: template<class T> void BST<T>::Deletepri(TreeNode<

XML节点进行添加,删除,查找和删除操作

从网上整理所得 XMLDocument来操作XML比较简单,虽然有时效率不是很高.代码如下 已知有一个XML文件(bookstore.xml)如下: <?xml version="1.0" encoding="gb2312"?><bookstore> <book genre="fantasy" ISBN="2-3631-4"> <title>Oberon's Legacy<

该文档举例说明了multimap的查找和删除元素的使用

该文档举例说明了multimap的查找和删除元素的使用. 其中,在使用迭代器遍历元素的时候,如果使用了删除迭代器的操作,那么需要小心迭代器失效的情况. /* 功能说明: multimap的查找和删除元素的使用举例 代码说明: 使用multimap的equal_range()方法来查找符合指定key的元素.使用erase来删除指定key的元素. 实现方式: 限制条件或者存在的问题: 无 */ #include <iostream> #include <string> #include