二叉查找树(BST)

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <stack>
#include <queue>
#include <Windows.h>
using namespace std;

typedef struct _Node
{
    int data;
    struct _Node *left;
    struct _Node *right;
    _Node()
    {
        data = 0;
        left = NULL;
        right = NULL;
    }
}Node, *_PNode;

//******************************************BST************************************************begin

//获取此节点子树的最小值
_PNode BSTGetMinNode(_PNode pNode)
{
    while (NULL != pNode->left)
    {
        pNode = pNode->left;
    }
    return pNode;
}

//获取此节点子树的最大值
_PNode BSTGetMaxNode(_PNode pNode)
{
    while (NULL != pNode->right)
    {
        pNode = pNode->right;
    }
    return pNode;
}

//BST节点的查找
bool BSTSearch(_PNode pRoot, int key)
{
    while (NULL != pRoot)
    {
        if (pRoot->data == key)
        {
            return true;
        }
        else if (pRoot->data > key)
        {
            pRoot = pRoot->left;
        }
        else
        {
            pRoot = pRoot->right;
        }
    }
    return false;
}

//BST的节点插入
void BSTInsertNode(_PNode &pRoot, int key)
{
    if (BSTSearch(pRoot, key))   //1、找到就返回
    {
        return;
    }
    _PNode pNode = new Node; 
    pNode->data = key;
    if (NULL == pRoot)
    {
        pRoot = pNode;
        return;
    }
    _PNode p = pRoot;
    _PNode pPre = NULL;
    while (NULL != p)     //2、找到插入节点的父节点
    {
        if (p->data > key)
        {
            pPre = p;
            p= p->left;
        }
        else
        {
            pPre = p;
            p= p->right;
        }
    }
    if (pPre->data > key)    //3、插入节点
    {
        pPre->left = pNode;
    }
    else 
    {
        pPre->right = pNode;
    }
}

//BST的节点删除
void BSTDeleteNode(_PNode &pRoot, int key)
{
    if (!BSTSearch(pRoot, key))   //1、没找到就返回
    {
        return;
    }
    _PNode pPreNode;
    _PNode pNode = pRoot;
    while (NULL != pNode)    //2、查找该节点
    {
        if (pNode->data == key)
        {
            break;
        }
        else if (pNode->data > key)
        {
            pPreNode = pNode;
            pNode = pNode->left;
        }
        else
        {
            pPreNode = pNode;
            pNode = pNode->right;
        }
    }
    if (NULL == pNode->left || NULL == pNode->right)  //3、该节点只有一条子树
    {
        if (NULL != pNode->left)
        {
            if (pNode == pRoot)
            {
                pRoot = pNode->left;
            }
            else if (pPreNode->left == pNode)
            {
                pPreNode->left = pNode->left;
            }
            else
            {
                pPreNode->right = pNode->left;
            }
        }
        else
        {
            {
                if (pNode == pRoot)
                {
                    pRoot = pNode->right;
                }
                else if (pPreNode->left == pNode)
                {
                    pPreNode->left = pNode->right;
                }
                else
                {
                    pPreNode->right = pNode->right;
                }
            }
        }
    }
    else  //4、该节点有左右子树
    {
        _PNode pPre = pNode;
        _PNode pSearch = pNode->right;
        while (NULL != pSearch->left)  //5、找该节点右子树的最小值
        {
            pPre = pSearch;
            pSearch = pSearch->left;
        }
        pNode->data = pSearch->data;
        if (pPre->left == pSearch)
        {
            pPre->left = pSearch->right;
        }
        else
        {
            pPre->right = pSearch->right;
        }
    }
}

//获取值为key节点的前驱
_PNode BSTGetPreNode(_PNode pRoot,int key)
{
    if (!BSTSearch(pRoot, key))
    {
        return NULL;
    }
    stack<_PNode> s;
    _PNode pNode = pRoot;
    while (NULL != pNode)
    {
        if (pNode->data == key)
        {
            break;
        }
        else if (pNode->data > key)
        {
            s.push(pNode);
            pNode = pNode->left;
        }
        else
        {
            s.push(pNode);
            pNode = pNode->right;
        }
    }
    if (NULL != pNode->left)  //有左子树,取该节点左子树的最大值
    {
        return BSTGetMaxNode(pNode->left);
    }
    else
    {
        _PNode p;
        while (!s.empty())
        {
            p = s.top();
            s.pop();
            if (p->left == pNode)
            {
                pNode = p;
            }
            else
            {
                return p;
            }
        }
    }
    return NULL;
}

//获取值为key节点的后继
_PNode BSTGetPostNode(_PNode pRoot, int key)
{
    if (!BSTSearch(pRoot, key))
    {
        return NULL;
    }
    stack<_PNode> s;
    _PNode pNode = pRoot;
    while (NULL != pNode)
    {
        if (pNode->data == key)
        {
            break;
        }
        else if (pNode->data > key)
        {
            s.push(pNode);
            pNode = pNode->left;
        }
        else
        {
            s.push(pNode);
            pNode = pNode->right;
        }
    }
    if (NULL != pNode->right)  //有右子树,取该节点右子树的最小值
    {
        return BSTGetMinNode(pNode->right);
    }
    else
    {
        _PNode p;
        while (!s.empty())
        {
            p = s.top();
            s.pop();
            if (p->right == pNode)
            {
                pNode = p;
            }
            else
            {
                return p;
            }
        }
    }
    return NULL;
}

//******************************************BST***********************************************end

//辅助函数,设置控制台的颜色
void SetConsoleTextColor(WORD dwColor)
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    if (INVALID_HANDLE_VALUE == handle)
    {
        return;
    }
    SetConsoleTextAttribute(handle, dwColor);
}

int _tmain(int argc, _TCHAR* argv[])
{
    _PNode pRoot1 = NULL;
    cout<<endl<<"******************建立BST二叉树********************"<<endl<<endl;
    int a[10] = {6, 7, 2, 1, 9, 5, 3, 10, 8, 4};
    for (int i = 0; i < 10; i++)
    {
        BSTInsertNode(pRoot1, a[i]);
    }
    MidTraversal(pRoot1);
    _PNode p;
    SetConsoleTextColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    cout<<endl<<"*****************输出BST二叉树前驱******************"<<endl<<endl;
    for (int i = 0; i < 10; i++)
    {
        p = BSTGetPreNode(pRoot1, a[i]);
        if (NULL != p)
        {
            cout<<a[i]<<"的前驱是"<<p->data<<endl;
        }
        else
        {
            cout<<a[i]<<"没有前驱"<<endl;
        }
    }
    SetConsoleTextColor(FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    cout<<endl<<"*****************输出BST二叉树后继******************"<<endl<<endl;
    for (int i = 0; i < 10; i++)
    {
        p = BSTGetPostNode(pRoot1, a[i]);
        if (NULL != p)
        {
            cout<<a[i]<<"的后继是"<<p->data<<endl;
        }
        else
        {
            cout<<a[i]<<"没有后继"<<endl;
        }
    }
    SetConsoleTextColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    cout<<endl<<"******************删除BST二叉树********************"<<endl<<endl;
    for (int i = 0; i < 10; i++)
    {
        BSTDeleteNode(pRoot1, a[i]);
        cout<<endl;
        MidTraversal(pRoot1);
        cout<<endl;
    }
    return 0;
}

运行界面如下:

原文地址:https://www.cnblogs.com/venow/p/2627232.html