数据结构之二叉树——排序(查找、搜索)树

//各种树的知识,不一定只是二叉搜索树,还有普通树,平衡二叉搜索树等,平衡二叉树比较复杂
#include <iostream>
#include <vector>
using namespace std;

class BSTreeNode//二叉排序树节点的定义
{
public:
    BSTreeNode() : m_nValue(0), tag(0), m_pParent(NULL), m_pLeft(NULL), m_pRight(NULL){};//默认构造函数
    BSTreeNode(int number) : m_nValue(number), tag(0), m_pParent(NULL), m_pLeft(NULL), m_pRight(NULL){};//自定义构造函数

public:
    int m_nValue;
    int tag;//tag用来在后序遍历的非递归版本中标记
    BSTreeNode* m_pParent;
    BSTreeNode* m_pLeft;
    BSTreeNode* m_pRight;
};

void CreateBSTree(BSTreeNode** pRoot, int dataArr[], int dataNum);//新建一棵二叉排序树,里面用到插入方法
void InsertBSTreeNode(BSTreeNode** pRoot, int value);//往二叉排序树中插入新节点
void PrintBSTree(BSTreeNode* pRoot);//打印二叉树,里面用中序遍历
BSTreeNode* SearchMinNode(BSTreeNode* pRoot);//查找值最小的节点
BSTreeNode* SearchMaxNode(BSTreeNode* pRoot);//查找值最大的节点
BSTreeNode* SearchNode_Recursively(BSTreeNode* pRoot, int value);//查找值为value的节点,递归
BSTreeNode* SearchNode_Normally(BSTreeNode* pRoot, int value);//查找值为value的节点,非递归
void DeleteBSTreeNode(BSTreeNode** pRoot, int value);//删除二叉搜索时的指定节点

void PreOrderTraverse_Recursively(BSTreeNode* pRoot);//前序遍历二叉树,递归
void MidOrderTraverse_Recursively(BSTreeNode* pRoot);//中序遍历二叉树
void PostOrderTraverse_Recursively(BSTreeNode* pRoot);//后序遍历二叉树
void PreOrderTraverse_Normally(BSTreeNode* pRoot);//前序遍历二叉树,非递归
void MidOrderTraverse_Normally(BSTreeNode* pRoot);
void PostOrderTraverse_Normally(BSTreeNode* pRoot);
void DepthFirstTraverse(BSTreeNode* pRoot);//深度优先遍历
void BreadthFirstTraverse(BSTreeNode* pRoot);//广度优先遍历

void CreateTree(BSTreeNode*& pRoot);//创建一棵普通的二叉树,这里直接用到BSTree的节点定义
                                           //根据先序遍历递归创建二叉树,当然也可以中序或者后序遍历方式创建二叉树
BSTreeNode* ReBuildTree1(){ return NULL; }//根据前序序列和中序序列重建二叉树,先不写了
BSTreeNode* ReBuildTree2(){ return NULL; }//根据后序序列和中序序列重建二叉树,先不写了
BSTreeNode* SortedArrayToBSTree(vector<int>& numbers);//将有序数组转化为平衡二叉搜索树
BSTreeNode* SortedArrayToBSTreeCore(int leftIndex, int rightIndex, vector<int>& numbers);

class ListNode
{
public:
    int m_nValue;
    ListNode* m_pNext;
};
BSTreeNode* SortedListToBSTree(ListNode* pHead);//将有序链表转化为平衡二叉搜索树
BSTreeNode* SortedListToBSTreeCore(ListNode* pHead, ListNode* pTail);

//一般二叉树的一些常见的简单算法题,这里就直接用平衡二叉树的节点代替了
int GetTreeMaxDepth(BSTreeNode* pRoot);//求二叉树的最大高度
int GetTreeMinDepth(BSTreeNode* pRoot);//求二叉树的最小高度
bool IsBalanceTree(BSTreeNode* pRoot);//判断二叉树是否平衡
bool IsSameTree(BSTreeNode* pRoot1, BSTreeNode* pRoot2);//判断两棵二叉树是否相等
bool IsSymmetricTree(BSTreeNode* pRoot);//判断是不是平衡二叉树
bool IsSymmetricTreeCore(BSTreeNode* pLeftNode, BSTreeNode* pRightNode);
BSTreeNode* InvertTree_Recursively_1(BSTreeNode* pRoot);//翻转二叉树,递归,不用交换,不太懂
BSTreeNode* InvertTree_Recursively_2(BSTreeNode* pRoot);//需要交换,好理解一点
BSTreeNode* InvertTree_Normally(BSTreeNode* pRoot);//需要交换,好理解一点



int main()
{
    BSTreeNode* pRoot = NULL;
    //InsertBSTreeNode(&pRoot, 5);
    //InsertBSTreeNode(&pRoot, 6);
    //InsertBSTreeNode(&pRoot, 6);

    int data[] = { 17, 12, 19, 10, 15, 18, 25, 8, 11, 13, 16, 22 };
    CreateBSTree(&pRoot, data, sizeof(data)/sizeof(int));
    //PreOrderTraverse_Recursively(pRoot);
    //cout << endl;
    //MidOrderTraverse_Recursively(pRoot);
    //cout << endl;
    //PostOrderTraverse_Recursively(pRoot);
    //cout << endl;

    //PrintBSTree(pRoot);
    //cout << endl;
    //InsertBSTreeNode(&pRoot, 3);
    //PrintBSTree(pRoot);
    //cout << endl;

    //BSTreeNode* pMinNode = NULL;
    //pMinNode = SearchMinNode(pRoot);
    //if (pMinNode != NULL) cout << pMinNode->m_nValue << endl;
    //BSTreeNode* pMaxNode = NULL;
    //pMaxNode = SearchMaxNode(pRoot);
    //if (NULL != pMaxNode) cout << pMaxNode->m_nValue << endl;

    //BSTreeNode* pNode = NULL;
    //pNode = SearchNode_Recursively(pRoot, 100);
    //if (pNode != NULL) cout << "Find the node!" << endl;
    //pNode = SearchNode_Normally(pRoot, 1);
    //if (pNode != NULL) cout << "Find the node!" << endl;

    //DeleteBSTreeNode(&pRoot, 25);
    //PrintBSTree(pRoot);
    //cout << endl;

    //PreOrderTraverse_Normally(pRoot);
    //cout << endl;
    //MidOrderTraverse_Normally(pRoot);
    //cout << endl;
    //PostOrderTraverse_Normally(pRoot);
    //cout << endl;
    //DepthFirstTraverse(pRoot);
    //cout << endl;
    //BreadthFirstTraverse(pRoot);
    //cout << endl;
    //CreateTree(pRoot);
    //if (pRoot != NULL) PrintBSTree(pRoot);
    //cout << endl;

    //vector<int> numbers = { 1, 2, 3 };
    //pRoot = SortedArrayToBSTree(numbers);
    //if (pRoot != NULL) PrintBSTree(pRoot);
    //ListNode* pHead = new ListNode();
    //ListNode* pNode1 = new ListNode();
    //ListNode* pNode2 = new ListNode();
    //pHead->m_nValue = 1; pHead->m_pNext = pNode1;
    //pNode1->m_nValue = 2; pNode1->m_pNext = pNode2;
    //pNode2->m_nValue = 3; pNode2->m_pNext = NULL;
    //pRoot = SortedListToBSTree(pHead);
    //if (pRoot != NULL) PrintBSTree(pRoot);
    //cout << endl;

    //int height = 0;
    //height = GetTreeMaxDepth(pRoot);
    //if (height != 0)cout << height << endl;
    //height = GetTreeMinDepth(pRoot);
    //if (height != 0)cout << height << endl;

    //bool isBalance = false;
    //isBalance = IsBalanceTree(pRoot);
    //if (isBalance) cout << "Yes,it is a balance tree!" << endl;
    //else cout << "No,it is not a balance tree!" << endl;
    //bool isSame = false;
    //isSame = IsSameTree(pRoot, pRoot);
    //if (isSame) cout << "Yes,they are same trees!" << endl;
    //else cout << "No,they are not same trees!" << endl;
    //bool isSymmetric = false;
    //isSymmetric = IsSymmetricTree(pRoot);
    //if (isSymmetric) cout << "Yes,it is a symmetric tree!" << endl;
    //else cout << "No,it is not a symmetric tree!" << endl;
    //PrintBSTree(pRoot);
    //cout << endl;
    //pRoot = InvertTree_Recursively_1(pRoot);
    //PrintBSTree(pRoot);
    //cout << endl;
    //pRoot = InvertTree_Recursively_2(pRoot);
    //PrintBSTree(pRoot);
    //cout << endl;

    PrintBSTree(pRoot);
    cout << endl;
    pRoot = InvertTree_Normally(pRoot);
    PrintBSTree(pRoot);
    cout << endl;




    system("pause");
    return 0;
}

void CreateBSTree(BSTreeNode** pRoot, int dataArr[], int dataNum)
{
    if (dataArr == NULL || dataNum <= 0)
    {
        cout << "Error:invalid parameters,can't create a BSTree!" << endl;
        return;
    }

    for (int i = 0; i < dataNum; ++i)
    {
        InsertBSTreeNode(pRoot, dataArr[i]);
    }
    return;
}

void InsertBSTreeNode(BSTreeNode** pRoot, int value)
{
    BSTreeNode* pNode = new BSTreeNode(value);//不需要在指定指针的指向为NULL了,因为构造函数里已经指定了。
    if (pNode == NULL)
    {
        cout << "节点内存分配失败!" << endl;
        return;
    }

    if (pRoot == NULL || *pRoot == NULL)
    {
        *pRoot = pNode;
        return;
    }

    BSTreeNode* pCurNode = *pRoot;
    BSTreeNode* pParentNode = NULL;
    while (pCurNode != NULL)
    {
        pParentNode = pCurNode;
        pCurNode = (value < pCurNode->m_nValue) ? pCurNode->m_pLeft : pCurNode->m_pRight;
    }

    if (value < pParentNode->m_nValue) pParentNode->m_pLeft = pNode;
    else if (value > pParentNode->m_nValue) pParentNode->m_pRight = pNode;
    else
    {
        cout << "Error:there is already a tree node whose value is the value you gave,can't insert!" << endl;
        delete pNode;
        pNode = NULL;
        return;
    }
}

void PrintBSTree(BSTreeNode* pRoot)
{
    MidOrderTraverse_Recursively(pRoot);
}

void PreOrderTraverse_Recursively(BSTreeNode* pRoot)
{
    if (pRoot == NULL) return;

    cout << pRoot->m_nValue << " ";
    PreOrderTraverse_Recursively(pRoot->m_pLeft);
    PreOrderTraverse_Recursively(pRoot->m_pRight);
}

void MidOrderTraverse_Recursively(BSTreeNode* pRoot)
{
    if (pRoot == NULL) return;

    MidOrderTraverse_Recursively(pRoot->m_pLeft);
    cout << pRoot->m_nValue << " ";
    MidOrderTraverse_Recursively(pRoot->m_pRight);
}

void PostOrderTraverse_Recursively(BSTreeNode* pRoot)
{
    if (pRoot == NULL) return;

    PostOrderTraverse_Recursively(pRoot->m_pLeft);
    PostOrderTraverse_Recursively(pRoot->m_pRight);
    cout << pRoot->m_nValue << " ";
}

#include <stack>
void PreOrderTraverse_Normally(BSTreeNode* pRoot)
{
    stack<BSTreeNode*> nodesStack;
    BSTreeNode* pNode = pRoot;
    while (pNode != NULL || !nodesStack.empty())
    {
        while (pNode != NULL)
        {
            cout << pNode->m_nValue << " ";
            nodesStack.push(pNode);
            pNode = pNode->m_pLeft;
        }
        if (!nodesStack.empty())
        {
            pNode = nodesStack.top();
            nodesStack.pop();
            pNode = pNode->m_pRight;
        }
    }
}

void MidOrderTraverse_Normally(BSTreeNode* pRoot)
{
    stack<BSTreeNode*> nodesStack;
    BSTreeNode* pNode = pRoot;
    while (pNode != NULL || !nodesStack.empty())
    {
        while (pNode != NULL)
        {
            nodesStack.push(pNode);
            pNode = pNode->m_pLeft;
        }
        if (!nodesStack.empty())
        {
            pNode = nodesStack.top();
            nodesStack.pop();
            cout << pNode->m_nValue << " ";
            pNode = pNode->m_pRight;
        }
    }
}

void PostOrderTraverse_Normally(BSTreeNode* pRoot)
{
    stack<BSTreeNode*> nodesStack;
    BSTreeNode* pNode = pRoot;
    while (pNode != NULL || !nodesStack.empty())
    {
        while (pNode != NULL)
        {
            nodesStack.push(pNode);
            pNode = pNode->m_pLeft;
        }
        if (!nodesStack.empty())
        {
            pNode = nodesStack.top();
            if (pNode->tag)
            {
                cout << pNode->m_nValue << " ";
                nodesStack.pop();
                pNode = NULL;
            }
            else
            {
                pNode->tag = 1;
                pNode = pNode->m_pRight;
            }
        }
    }
}

void DepthFirstTraverse(BSTreeNode* pRoot)
{
    stack<BSTreeNode*> nodesStack;
    BSTreeNode* pNode = pRoot;
    nodesStack.push(pNode);

    while (!nodesStack.empty())
    {
        pNode = nodesStack.top();
        cout << pNode->m_nValue << " ";
        nodesStack.pop();
        if (pNode->m_pRight != NULL) nodesStack.push(pNode->m_pRight);
        if (pNode->m_pLeft != NULL) nodesStack.push(pNode->m_pLeft);
    }
}

#include <queue>
void BreadthFirstTraverse(BSTreeNode* pRoot)
{
    queue<BSTreeNode*> nodesQueue;
    BSTreeNode* pNode = pRoot;
    nodesQueue.push(pNode);
    while (!nodesQueue.empty())
    {
        pNode = nodesQueue.front();
        cout << pNode->m_nValue << " ";
        nodesQueue.pop();
        if (pNode->m_pLeft != NULL) nodesQueue.push(pNode->m_pLeft);
        if (pNode->m_pRight != NULL) nodesQueue.push(pNode->m_pRight);
    }
}

BSTreeNode* SearchMinNode(BSTreeNode* pRoot)
{
    if (NULL == pRoot)
    {
        cout << "二叉树搜索树为空,无法查找值为最小的节点!" << endl;
        return NULL;
    }
    if (NULL == pRoot->m_pLeft) return pRoot;

    else return SearchMinNode(pRoot->m_pLeft);
}

BSTreeNode* SearchMaxNode(BSTreeNode* pRoot)
{
    if (NULL == pRoot)
    {
        cout << "二叉树搜索树为空,无法查找值为最小的节点!" << endl;
        return NULL;
    }
    if (NULL == pRoot->m_pRight) return pRoot;
    else return SearchMaxNode(pRoot->m_pRight);
}

BSTreeNode* SearchNode_Recursively(BSTreeNode* pRoot, int value)
{
    if (NULL == pRoot)
    {
        cout << "Tree is empty or has no the target node,can't search the node!" << endl;
        return NULL;
    }

    if (value > pRoot->m_nValue) return SearchNode_Recursively(pRoot->m_pRight, value);
    else if (value < pRoot->m_nValue) return SearchNode_Recursively(pRoot->m_pLeft, value);
    else return pRoot;
}

BSTreeNode* SearchNode_Normally(BSTreeNode* pRoot, int value)
{
    if (NULL == pRoot)
    {
        cout << "Tree is empty,can't search the node!" << endl;
        return NULL;
    }

    BSTreeNode* pNode = pRoot;
    while (pNode != NULL)
    {
        if (pNode->m_nValue == value) return pNode;
        else pNode = (value < pNode->m_nValue) ? pNode->m_pLeft : pNode->m_pRight;
    }

    cout << "There is no node whose value is wanted,can't find it!" << endl;
    return NULL;
}

void DeleteBSTreeNode(BSTreeNode** pRoot, int value)
{
    if (NULL == pRoot || NULL == *pRoot)
    {
        cout << "二叉树为空,无法删除!" << endl;
        return;
    }

    BSTreeNode* pNode = *pRoot;
    if (pNode->m_nValue == value)
    {
        if (pNode->m_pLeft == NULL && pNode->m_pRight == NULL)
            *pRoot = NULL;
        else if (pNode->m_pLeft != NULL && pNode->m_pRight == NULL)
            *pRoot = pNode->m_pLeft;
        else if (pNode->m_pLeft == NULL && pNode->m_pRight != NULL)
            *pRoot = pNode->m_pRight;
        else
        {
            BSTreeNode* pCurNode = pNode->m_pRight;
            BSTreeNode* pParentNode = NULL;
            if (pCurNode->m_pLeft == NULL) pCurNode->m_pLeft = pNode->m_pLeft;
            else
            {
                while (pCurNode->m_pLeft != NULL)
                {
                    pParentNode = pCurNode;
                    pCurNode = pCurNode->m_pLeft;
                }
                pParentNode->m_pLeft = pCurNode->m_pRight;
                pCurNode->m_pLeft = pNode->m_pLeft;
                pCurNode->m_pRight = pNode->m_pRight;
            }
            *pRoot = pCurNode;
        }
        delete pNode;
        pNode = NULL;
    }
    else if (pNode->m_nValue > value) DeleteBSTreeNode(&(pNode->m_pLeft), value);
    else DeleteBSTreeNode(&(pNode->m_pRight), value);
}

void CreateTree(BSTreeNode*& pRoot)
{
    int value = 0;
    cin >> value;
    if (0 == value) pRoot = NULL;
    else
    {
        pRoot = new BSTreeNode(value);//根据构造函数确定该语句

        CreateTree(pRoot->m_pLeft);
        CreateTree(pRoot->m_pRight);
    }
}

BSTreeNode* SortedArrayToBSTree(vector<int>& numbers)
{
    return SortedArrayToBSTreeCore(0, numbers.size() - 1, numbers);
}
BSTreeNode* SortedArrayToBSTreeCore(int leftIndex, int rightIndex, vector<int>& numbers)
{
    if (leftIndex > rightIndex) return NULL;
    int midIndex = (rightIndex - leftIndex) / 2 + leftIndex;
    BSTreeNode* pTreeRoot = new BSTreeNode(numbers[midIndex]);
    pTreeRoot->m_pLeft = SortedArrayToBSTreeCore(leftIndex, midIndex - 1, numbers);
    pTreeRoot->m_pRight = SortedArrayToBSTreeCore(midIndex + 1, rightIndex, numbers);

    return pTreeRoot;
}

BSTreeNode* SortedListToBSTree(ListNode* pHead)
{
    if (pHead == NULL) return NULL;
    return SortedListToBSTreeCore(pHead, NULL);
}
BSTreeNode* SortedListToBSTreeCore(ListNode* pHead, ListNode* pTail)
{
    ListNode* pSlow = pHead;
    ListNode* pFast = pHead;
    if (pHead == pTail) return NULL;

    while (pFast != pTail && pFast->m_pNext != pTail)
    {
        pFast = pFast->m_pNext->m_pNext;
        pSlow = pSlow->m_pNext;
    }
    BSTreeNode* pTreeRoot = new BSTreeNode(pSlow->m_nValue);
    pTreeRoot->m_pLeft = SortedListToBSTreeCore(pHead, pSlow);
    pTreeRoot->m_pRight = SortedListToBSTreeCore(pSlow->m_pNext, pTail);
    return pTreeRoot;
}

int GetTreeMaxDepth(BSTreeNode* pRoot)
{
    if (pRoot == NULL) return 0;
    else
    {
        int leftDepth = GetTreeMaxDepth(pRoot->m_pLeft);
        int rightDepth = GetTreeMaxDepth(pRoot->m_pRight);

        return (1 + max(leftDepth, rightDepth));
    }
}

int GetTreeMinDepth(BSTreeNode* pRoot)
{
    if (pRoot == NULL) return 0;

    if (pRoot->m_pLeft == NULL)
        return GetTreeMinDepth(pRoot->m_pRight) + 1;
    else if (pRoot->m_pRight == NULL)
        return GetTreeMinDepth(pRoot->m_pLeft) + 1;
    else
        return min(GetTreeMinDepth(pRoot->m_pLeft), GetTreeMinDepth(pRoot->m_pRight)) + 1;
}

bool IsBalanceTree(BSTreeNode* pRoot)
{
    if (pRoot == NULL) return true;

    if (abs(GetTreeMaxDepth(pRoot->m_pLeft) - GetTreeMaxDepth(pRoot->m_pRight)) > 1)
        return false;
    return IsBalanceTree(pRoot->m_pLeft) && IsBalanceTree(pRoot->m_pRight);
}

bool IsSameTree(BSTreeNode* pRoot1, BSTreeNode* pRoot2)
{
    if (pRoot1 == pRoot2) return true;

    if ((pRoot1 != NULL && pRoot2 == NULL) || (pRoot1 == NULL && pRoot2 != NULL) ||
        pRoot1->m_nValue != pRoot2->m_nValue)
        return false;
    return IsSameTree(pRoot1->m_pLeft, pRoot2->m_pLeft) && IsSameTree(pRoot1->m_pRight, pRoot2->m_pRight);
}

bool IsSymmetricTree(BSTreeNode* pRoot)
{
    if (pRoot == NULL) return true;
    else return IsSymmetricTreeCore(pRoot->m_pLeft, pRoot->m_pRight);

    return false;
}
bool IsSymmetricTreeCore(BSTreeNode* pLeftNode, BSTreeNode* pRightNode)
{
    if (pLeftNode == NULL && pRightNode == NULL) return true;
    if (pLeftNode == NULL || pRightNode == NULL) return false;
    if (pLeftNode->m_nValue != pRightNode->m_nValue) return false;

    return IsSymmetricTreeCore(pLeftNode->m_pLeft, pRightNode->m_pRight) &&
        IsSymmetricTreeCore(pLeftNode->m_pRight, pRightNode->m_pLeft);
}

BSTreeNode* InvertTree_Recursively_1(BSTreeNode* pRoot)//不太懂
{
    if (pRoot == NULL) return NULL;
    BSTreeNode* tmpNode = pRoot->m_pRight;
    pRoot->m_pRight = InvertTree_Recursively_1(pRoot->m_pLeft);
    pRoot->m_pLeft = InvertTree_Recursively_1(tmpNode);

    return pRoot;
}
BSTreeNode* InvertTree_Recursively_2(BSTreeNode* pRoot)
{
    if (pRoot == NULL) return NULL;
    InvertTree_Recursively_2(pRoot->m_pLeft);
    InvertTree_Recursively_2(pRoot->m_pRight);
    swap(pRoot->m_pLeft, pRoot->m_pRight);

    return pRoot;
}

#include <queue>
BSTreeNode* InvertTree_Normally(BSTreeNode* pRoot)
{
    if (pRoot == NULL) return NULL;
    queue<BSTreeNode*> nodesQueue;
    nodesQueue.push(pRoot);
    while (nodesQueue.size() > 0)
    {
        BSTreeNode* pNode = nodesQueue.front();
        nodesQueue.pop();
        if (pNode != NULL)
        {
            nodesQueue.push(pNode->m_pLeft);
            nodesQueue.push(pNode->m_pRight);
            swap(pNode->m_pLeft, pNode->m_pRight);
        }
    }
    return pRoot;
}

猜你喜欢

转载自blog.csdn.net/Alexander_1314/article/details/82154611