二叉搜索树的插入和删除

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

相关文章推荐

二叉搜索树的插入

(Swift 实现)二叉搜索树 —— 创建,最大,最小,查找,插入,删除,前驱,后继,中序遍历

了解了二叉堆之后,二叉搜索树就好说了,就是一个节点,左边的子节点是不可能比他大的,右边的子节点是一定大于它的,想了半天终于把创建给写好了。直接看代码import UIKitvar str = "二叉搜...

二叉搜索树的创建、遍历、插入、删除(C++版本)

#include #include using namespace std; class BinarySearchTree { private: struct tree_...

二叉搜索树(插入、删除、迭代遍历)

《算法导论》里面的代码真实简洁,看的很舒服,实现也很简单!!! 头文件:bst.h #ifndef _BST_ #define _BST_ struct Node { int data; N...

【算法导论】二叉搜索树的插入和删除

阐述二叉搜索树的插入和删除节点操作。

数据结构—二叉搜索树的创建、结点的插入和删除

代码如下: 头文件StudyBST.h #define TRUE 1 #define ERROR 0 #define OK 1 #define REEO...

二叉搜索树的查询、插入与删除操作(Binary Search Tree, Search, Insert, Delete)(C++)

一、概念     设 x 是二叉搜索树中的一个结点。如果 y 是 x 左子树中的一个结点,那么 y.key ≦ x.key。如果 y 是 x 右子树中的一个结点,那么 y.key ≧ x.key。 ...

二叉搜索树的定义、查找、插入和删除

二叉搜索树的定义 二叉搜索树,也称有序二叉树,排序二叉树,是指一棵空树或者具有下列性质的二叉树: 1. 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 2. 若任意节点的...

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

对于查找和插入操作相对来说比较简单,删除操作则需要考虑的情况较多。 比如有以下些情况,可能有些可以合并,但是我没想到更好的方法,因此代码里有一堆if else,虽然我不喜欢写这样的代码,但也没找到更好...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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