树-二叉查找树

前提是你 提交于 2019-11-26 14:58:23

二叉查找树,二叉搜索树,Binary Search Tree

二叉查找树性质:左孩子<双亲<右孩子

若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

任意节点的左、右子树也分别为二叉查找树。

没有键值相等的节点(no duplicate nodes)。

二叉查找树插入与删除

插入

1.若当前的二叉查找树为空,则插入的元素为根节点;

2.若插入的元素值小于根节点值,则将元素插入到左子树中;

3.若插入的元素值不小于根节点值,则将元素插入到右子树中。

删除

分三种情况进行处理:

1.p为叶子节点。

直接删除该节点,再修改其父节点的指针(注意分是根节点和不是根节点)。

2.p为单支节点(即只有左子树或右子树)。

让p的子树与p的父亲节点相连,删除p即可(注意分是根节点和不是根节点)。

3.p的左子树和右子树均不空。

(找后继,次大值):找到p的后继y,因为y一定没有左子树,所以可以删除y,并让y的父亲节点成为y的右子树的父亲节点,并用y的值代替p的值;

二叉查找树实现

//BSTree.h
#ifndef BSTREE_HXX
#define BSTREE_HXX

#include <iostream>
using namespace std;

template <class T>
class BSTNode
{
    public:
        T key;
        BSTNode *leftchild;
        BSTNode *rigthchild;
        BSTNode *parent;

        BSTNode(T value, BSTNode *p, BSTNode *l, BSTNode *r):\
                key(value),parent(),leftchild(l),right(r){}
};

template <class T>
class BSTree
{
    private:
        BSTNode<T> *root;
    public:
        BSTree();
        ~BSTree();
       
        void preOrder();//先序遍历
        void inOrder()://中序遍历
        void postOrder();//后序遍历
       
        BSTNode<T> * search(BSTNode<T> *tree,T key);//递归查找
        BSTNode<T> * iterativeSearch(T key);//非递归查找
       
        T minimum();//查找最小结点
        T maximum();//查找最大结点
       
        BSTNode<T> * successor(BSTNode<T> *x);//查找x的后继结点
        BSTNode<T> * predecessor(BSTNode<T> *x);//查找x的前驱结点
       
        void insert(T key);//插入
        void remove(T key);//删除
        void destroy();//销毁二叉树   
}
#endif //BSTREE_HXX

//BSTree.cpp
#include "BSTree.h"
#include <iostream>
using namespace std;

template <class T>
BSTree<T>::BSTree():root(NULL)
{
   
}

template <class T>
BSTree<T>::~BSTree()
{
    destroy();
}

template <class T>
void BSTree<T>::preOrder()
{
    BSTNode<T> * tree = root;
    if(tree != NULL)
    {
        cout<<tree->key<<" ";
        preOrder(tree->leftchild);
        preOrder(tree0>rightchild);
    }
}

template <class T>
void BSTree<T>::inOrder()
{
    BSTNode<T> * tree = root;
    if(tree != NULL)
    {
        inOrder(tree->leftchild);
        cout<<tree->key<<" ";
        inOrder(tree0>rightchild);
    }
}

template <class T>
void BSTree<T>::postOrder()
{
    BSTNode<T> * tree = root;
    if(tree != NULL)
    {
        postOrder(tree->leftchild);
        postOrder(tree0>rightchild);
        cout<<tree->key<<" ";
    }
}

template <class T>
BSTNode<T> * BSTree<T>::search(BSTNode<T> *tree,T key)
{
    tree = root;
    if(tree == NULL || tree->key == key)
        return tree;
    if(key < tree->key)
        return search(tree->leftchild,key);
    if(key > tree->key)
        return search(tree->rightchild,key);
}

template <class T>
BSTNode<T> * BSTree<T>::iterativeSearch(T key)
{
    BSTNode<T> * tree = root;
    while((tree != NULL) && (tree->key != key))
    {
        if(key < tree->key)
            tree = tree->leftchild;
        else
            tree = tree->rightchild;
    }
    return tree;
}

template <class T>
T BSTree<T>::minimum()
{
    BSTNode<T> * tree = root;
    if(tree == NULL)
        return NULL;
    while(tree->leftchild != NULL)
        tree = tree->leftchild;
    return tree->key;
}

template <class T>
T BSTree<T>::maximum()
{
    BSTNode<T> * tree = root;
    if(tree == NULL)
        return NULL;
    while(tree->rightchild != NULL)
        tree = tree->rightchild;
    return tree->key;
}

//后继结点,次小结点
template <class T>
BSTNode<T> * BSTree<T>::successor(BSTNode<T> *x)
{
    // 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
    if(x->rightchild != NULL)
        return minimum(x->rightchild);
    // 如果x没有右孩子。则x有以下两种可能:
    // (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
    // (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结
    BSTNode<T> * p = x->parent;
    while((p != NULL) && (x == p->rightchild))
    {
        x = p;
        p = p->parent;
    }
    return p;
}

//前驱结点,次大结点
template <class T>
BSTNode<T> * BSTree<T>::predecessor(BSTNode<T> *x)
{
   
    if(x->leftchild != NULL)
        return minimum(x->leftchild);
       
    BSTNode<T> * p = x->parent;
    while((p != NULL) && (x == p->leftchild))
    {
        x = p;
        p = p->parent;
    }
    return p;
}

template <class T>
void BSTree<T>::insert(T key)
{
    BSTNode<T> * p = NULL;
    BSTNode<T> * x = root;
    while(x!=NULL)
    {
        p = x;
        if(key < x->key)
            x = x->leftchild;
        else
            x = x->rightchild;
    }
    BSTNode<T> * newNode = new BSTNode<T>;
    newNode->key = key;
    newNode->parent = p;
    if(p == NULL)
        root = newNode;
    elseif(newNode->key < p->key)
        p->leftchild = newNode;
    else
        p->rightchild = newNode;
}

template <class T>
void BSTree<T>::remove(T key)
{
    BSTNode<T> * x = NULL;
    BSTNode<T> * y = NULL;
    BSTNode<T> * tree = root;
   
    BSTNode<T> * removeNode = search(root,key);
   
    if((removeNode->leftchild == NULL) || (removeNode->rightchild == NULL))
        y = removeNode;
    else
        y = successor(removeNode);
   
    if(y->leftchild != NULL)
        x = y->leftchild;
    else
        x = y->rightchild;
       
    if(x != NULL)
        x->parent = y->parent;
       
    if(y->parent == NULL)
        tree = x;
    elseif(y == y->parent->leftchild)
        y->parent->leftchild = x;
    else
        y->parent->rightchild = x;
       
    if(y != removeNode)
        removeNode->key = y->key;
    delete y;
}

template <class T>
void BSTree<T>::destroy(BSTNode<T> * tree)
{
    tree = root;
    if(tree == NULL)
        return;
    if(tree->leftchild != NULL)
        return destroy(tree->leftchild);
    if(tree->rightchild != NULL)
        return destroy(tree->rightchild);
   
    delete tree;
    tree = NULL;
}

转载于:https://www.cnblogs.com/lucas-hsueh/p/3730503.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!