二叉搜索树的插入和删除

转载 2012年03月28日 11:05:11

题目:2叉搜索树的插入和删除 
要求
(1)任意选顶一个2叉搜索树用先序遍历 中序遍历 和后序遍历显示该2叉搜索树

(2)动态显示出在2叉搜索树中插入一个元素时树的变化过程 要求演示出所有可能的情况

(3)动态显示出 在2叉搜索树中删除一个元素时的变化过程要求演示出所有的可能的情况 

#include <iostream.h>
#define max 10
struct BinTreeNode                                                                             //二叉查找树的节点结构体
{
    int m_data;
    struct BinTreeNode *lchild, *rchild;
    BinTreeNode(int item, BinTreeNode *left = NULL, BinTreeNode *right = NULL)
        : m_data(item), lchild(left), rchild(right)  //构造函数默认的lchild,rchild为NULL
    {
    }
};

class  BinaryTree                                                                       //二叉搜索树类
{

private:
    BinTreeNode *root;   //根节点指针

public:
    BinaryTree()
    {
        root = NULL;
    }
    
 //迭带插入的方法建二叉搜索树
    void Insert(const int node)                                                
    {                                     
        BinTreeNode *currentpointer;        //当前节点指针  
        BinTreeNode *parentpointer;         //父亲节点指针    
        BinTreeNode *newpointer; 
        //ptr必须为根节点指针的引用
        BinTreeNode *ptr = root;
        newpointer = new BinTreeNode(node); //新动态分配一个节点

        if(root == NULL)    //如果此时树为空,返回新开辟的节点
        {
            root = newpointer;
        }
        else
        {
            currentpointer = ptr;        //保存root指针
   //一直移动到是使parentpointer指向叶子节点而currentpointer为NULL
            while(currentpointer != NULL)    //当当前节点不为空的情况下
            {
                parentpointer = currentpointer; //用指向父亲节点的指针保存当前指针

                if(currentpointer->m_data > node)
                {
                    currentpointer = currentpointer->lchild;
                }
                else
                {
                    currentpointer = currentpointer->rchild;
                }
            }
            //以下是将节点插入
            if(parentpointer->m_data > node)
            {
                parentpointer->lchild = newpointer;
            }
            else
            {
                parentpointer->rchild = newpointer;
            }
        }
    }

 //创建方法,依次插入
    BinTreeNode *Creat(int data[],int len) 
    {
        for(int i=0; i<len; i++)
        {
            Insert(data[i]);
        }
        return root;
    }
    
    void PreOrder()
    {
        cout<<"前序遍历的结果为:";
        PrePrint(root);
    }

    void InOrder()
    {
        cout<<"中序遍历的结果为:";
        InPrint(root);
    }

    void PostOrder()
    {
        cout<<"后序遍历的结果为:";
        PostPrint(root);
    }

    void Count()
    {
        cout<<endl;
        cout<<"叶子节点数为:"<<CountLeafs(root)<<endl;
    }

    void PrePrint(BinTreeNode *p) //前序遍历
    {
        if(p != NULL)
        {
            cout << p->m_data << ',';
            PrePrint(p->lchild);
            PrePrint(p->rchild);
        }
    }

    void InPrint(BinTreeNode *p)  //中序遍历
    {
        if(p != NULL)
        {
            InPrint(p->lchild);
            cout<< p->m_data<<',';
            InPrint(p->rchild);
        }
    }
    
    
    void PostPrint(BinTreeNode *p)  //后序遍历
    {
        if(p != NULL)
        {
            PostPrint(p->lchild);
            PostPrint(p->rchild);
            cout<< p->m_data<< ',';
        }
    }

    BinTreeNode * Find(const int &c)  //用迭带的方法寻找特定的节点
    {
        BinTreeNode *pCurrent = root;
        if(pCurrent  != NULL)
        {
            while(pCurrent  != NULL)
            {
                if(pCurrent->m_data == c)
                {
                    return pCurrent;
                }
                else 
                {
                    if(c > pCurrent->m_data)
                        pCurrent  = pCurrent->rchild;
                    else
                        pCurrent  = pCurrent ->lchild;
                }
            }
        }
        return NULL;
    }
    
    bool DeleteBT(const int &key)   //删除节点的函数定义
    {
        BinTreeNode *q, *s;
        BinTreeNode *current = root; //找到要删除的节点
        BinTreeNode *prt = NULL;    //current的父亲节点

        while ((NULL != current) && (current->m_data != key))
                                   //通过查找找到值为key的节点和它的父亲节点
        {
            prt = current;
              
             if (current->m_data > key)
                     current = current->lchild;
             else
                     current = current->rchild;
        }

        if(current == NULL) //current为NULL说明节点不存在
        {
            cout<<"没有此节点!"<<endl;
            return false;
        }
        if(current->lchild == NULL && current->rchild == NULL)
                       //当找到的节点即没有左孩子也没有右孩子
        {
            if(current == root)
            {
                root = NULL;
            }
            else 
            {
                if(current == prt->lchild)
                {
                    prt->lchild = NULL;
                }
                else
                {
                    prt->rchild = NULL;
                }
            }
        }
        if(current->lchild == NULL && current->rchild != NULL)
                        //当找到的节点有右孩子而没有左孩子
        {
            if(current == root)
            {
                current = current->rchild;
            }
            else 
            {
                if(current == prt->lchild)  //如果当前节点是prt指向节点的左孩子
                {
                    prt->lchild = current->rchild;
                }
                else
                {
                    prt->rchild = current->rchild;
                }
            }
        }
        if(current->rchild == NULL && current->lchild != NULL) 
                                        //如果当前节点有左孩子而没有右孩子
        {
            if(current == root)
            {
                current = current->lchild;
            }
            else
            {
                if(current == prt->lchild)
                {
                    prt->lchild = current->lchild;
                }
                else
                {
                    prt->rchild = current->lchild;
                }
            }
        }

        if(current ->lchild != NULL && current->rchild != NULL)//当前节点左右孩子都有
        {
            q = current;    //用q保存current节点指针
            s = current;    //s是current的前驱指针

            current = current->lchild;
            //先向左走
            while(current->rchild) //然后向右走到尽头,其实就是寻找左子树当中最大的节点
            {                      //补充:寻找右子树当中最小的节点也是可以的
                s = current;       //s指向current的前驱
                current = current->rchild;
            }

            q->m_data = current->m_data;  //用找到的节点替换当前节点
        
            if(q != s)                    //将current节点从树中拆下来
                s->rchild = current->lchild;
            else
                q->lchild = current->lchild;
        }
        delete current;        //释放current指向的空间
        current = NULL;
        return true;
    }

    void destroy(BinTreeNode *current) //销毁二叉树
    {
        if(current != NULL)
        {
            destroy(current->lchild);
            destroy(current->rchild);
            delete current;
            current = NULL;
        }
    }

    int CountLeafs(BinTreeNode *current)
    {
        if(current == NULL)
        {
            return 0;
        }
        else 
        {
            if( current->lchild == NULL  &&  current->rchild == NULL )
            {
                return 1;
            }
            else
            {
                int num1 = CountLeafs(current->lchild);
                int num2 = CountLeafs(current->rchild);
                return (num1+num2);
            }
        }
    }

    virtual  ~BinaryTree() 
    {
        destroy(root);
    }
};
void main()
{
    BinaryTree myTree;
    int a[]={6, 3, 4, 7, 8, 2, 5, 9, 0, 1};
 //输出
 cout<<"(1)输出部分:"<<endl;
    myTree.Creat(a, max);  //创建二叉搜索树
    myTree.PreOrder();     //先序遍历
 cout<<endl;
    myTree.InOrder();      //中序遍历
 cout<<endl;
    myTree.PostOrder();    //后序遍历
 cout<<endl<<endl;
 //插入
 cout<<"(2)插入部分:"<<endl;
 int x;
 cout<<"输入你想要插入的节点:";
 cin>>x;
 myTree.Insert(x);
 myTree.InOrder();      //中序遍历
    cout<<endl<<endl;

 //删除
 cout<<"(3)删除部分:"<<endl;
    cout<<"输入一个你想删除的节点: ";
    cin>>x;
    if(myTree.DeleteBT(x))  //进行删除
        cout<<"删除成功!"<<endl;
    else
        cout<<"删除失败!"<<endl;
    myTree.InOrder();      //中序遍历
 cout<<endl<<endl;

 //查询
 cout<<"(4)查询部分:"<<endl;
 cout<<"输入你想要找的节点";
    cin>>x;
    if(myTree.Find(x))     //进行查找
        cout<<"查找成功!"<<endl;
    else
        cout<<"查找失败!"<<endl;
}

二叉搜索树的插入

  • 2015年12月22日 21:40
  • 5KB
  • 下载

二叉搜索树(BST)的创建、插入、查找和删除

树的结构体定义 struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), le...

平衡二叉搜索树(AVL)插入和删除的java代码实现

AVL树节点的声明代码: package geeksgeeks.avl; public class TreeNode {        int key ;   ...

二叉搜索树的插入,删除,查找操作

//头文件 //BinaryTreeNode.h #ifndef BINARYTREENODE_H #define BINARYTREENODE_H template class BinaryTree...

二叉搜索树的插入建立与结点删除

//二叉搜索树的删除 #include #include typedef struct Node { int data; struct Node *leftChild;...

[C++]数据结构:平衡的二叉搜索树之AVL树的结构特点与基础插入删除操作

在向大家介绍AVL树之前,我们先来看一下二叉搜索树的缺点。 BST的高度受输入顺序影响会有比较大的波动。 最好的高度为O(log n): 最坏的高度为O(n): 这样不稳定的结构不是我们想要的数...

Java 实现二叉搜索树的创建、查找、插入、删除结点

二叉搜索树特点:左孩子结点值比当前结点值小,右孩子结点值比当前值大或等于当前值。本文假设树中的结点值不存在相同的两项或多项。 一、二叉搜索树的创建  1、首先定义结点类     代码如下: clas...
  • lingzhm
  • lingzhm
  • 2015年03月20日 20:51
  • 1794

二叉搜索树的根插入、选择、删除、合并、排序等操作的实现

源代码如下: 这里的Key 不当为关键字对待, 而是把Item.c作为关键字对待 #include #include //#define Key int typedef int...

二叉搜索树(BST)递归与非递归的插入、删除、查找的实现

昨天碰到了二叉搜索树(BST)这种数据结构,索性详细的学习了一遍。BST的定义: 如果一棵树的左子树不为空,那么其所有节点的值均小于其根结点的值,如果右子树不为空,那么其所有节点的值均大于其...
  • s_h_r
  • s_h_r
  • 2016年03月03日 18:06
  • 1587
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:二叉搜索树的插入和删除
举报原因:
原因补充:

(最多只允许输入30个字)