線索二叉樹

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
BinaryTreeThreading.h

#pragma once
#include<iostream>
using namespace std;

enum PointerTag
{
    LINK, //指針,指向左右孩子
    THREAD, //線索,指向前驅或後繼
};

template<class T>
struct BinTreThrNode
{
    BinTreThrNode(const T& x)
    :_value(x)
    , _leftChild(NULL)
    , _rightChild(NULL)
    , _LTag(LINK)
    , _RTag(LINK)
    {}

    T _value;
    BinTreThrNode<T>* _leftChild;
    BinTreThrNode<T>* _rightChild;
    PointerTag _LTag;
    PointerTag _RTag;
};

template<class T>
class BinaryTreeThread
{
public:
    BinaryTreeThread(T* arr, size_t size)
    {
        int index = 0;
        _CreateTree(_root,arr,size,index);
    }
    void InOrderThearding() //中序遍歷線索化
    {
        BinTreThrNode<T>* prev = NULL;
        _InOrderThearding(_root,prev);
    }
    void PrevOrderThearding() //前序遍歷線索化
    {
        BinTreThrNode<T>* prev = NULL;
        _PrevOrderThearding(_root, prev);
    }
    void PostOrderThearding() //後序遍歷線索化
    {
        BinTreThrNode<T>* prev = NULL;
        _PostOrderThearding(_root, prev);
    }
    void InOrder()
    {
        cout << "中序遍歷:";
        BinTreThrNode<T>* cur = _root;
        while (cur)
        {
            while (cur && cur->_LTag != THREAD)
            {
                cur = cur->_leftChild;
            }
            cout << cur->_value << " ";
            if (cur->_RTag != THREAD)
            {
                cur = cur->_rightChild;
            }
            else
            {
                cur = cur->_rightChild;
                cout << cur->_value << " ";
                while (cur->_RTag == THREAD) //防止死循環
                {
                    cur = cur->_rightChild;
                    cout << cur->_value << " ";
                }
                cur = cur->_rightChild;
            }
        }
        cout << endl;
    }
    void PrevOrder()
    {
        cout << "前序遍歷:";
        BinTreThrNode<T>* cur = _root;
        while (cur)
        {
            while (cur->_LTag != THREAD)
            {
                cout << cur->_value<<" ";
                cur = cur->_leftChild;
            }
            cout << cur->_value<<" ";
            cur = cur->_rightChild;
        }
    }
    void PostOrder()
    {
        cout << "後序遍歷:";
        BinTreThrNode<T>* cur = _root;
        BinTreThrNode<T>* prev = _root;
        while (cur)
        {
            while (cur->_LTag != THREAD && prev->_rightChild != cur)
            {
                cur = cur->_leftChild;
            }
            cout << cur->_value << " ";
            if (cur->_RTag == THREAD)
            {
                prev = cur;
            }
            if (prev->_rightChild == cur && cur != _root) //防止死循環
            {
                cur = _root;
            }
            if (cur->_rightChild != prev)
            {
                cur = cur->_rightChild;
            }
            else
            {
                return;
            }
        }
    }
private:
    void _CreateTree(BinTreThrNode<T>*& root, T* arr, size_t size,int& index) //index要用引用
    {
        if (arr[index] != '#' && index < size)
            {
                root = new BinTreThrNode<T>(arr[index]);
                _CreateTree(root->_leftChild,arr,size,++index);
                _CreateTree(root->_rightChild,arr,size,++index);
            }
    }
    void _InOrderThearding(BinTreThrNode<T>*& root, BinTreThrNode<T>*& prev)
    {
        BinTreThrNode<T>* cur = root;
        if (cur && cur->_leftChild)
        {
            _InOrderThearding(cur->_leftChild, prev);
        }
        if (cur->_leftChild == NULL)
        {
            cur->_leftChild = prev;
            cur->_LTag = THREAD;
        }
        if (prev && prev->_rightChild == NULL)
        {
            prev->_rightChild = cur;
            prev->_RTag = THREAD;
        }
        prev = cur;
        if (cur && cur->_rightChild)
        {
            _InOrderThearding(cur->_rightChild, prev);
        }
    }

    void _PrevOrderThearding(BinTreThrNode<T>*& root, BinTreThrNode<T>*& prev)
    {
        BinTreThrNode<T>* cur = root;
        if (cur->_leftChild == NULL)
        {
            cur->_LTag = THREAD;
            cur->_leftChild = prev;
        }
        if (prev && prev->_rightChild == NULL)
        {
            prev->_rightChild = cur;
            prev->_RTag = THREAD;
        }
        prev = cur;
        if (cur && cur->_LTag != THREAD)
        {
            _PrevOrderThearding(cur->_leftChild, prev);
        }
        if (cur->_rightChild && cur->_RTag != THREAD)
        {
            _PrevOrderThearding(cur->_rightChild, prev);
        }
    }
    void _PostOrderThearding(BinTreThrNode<T>*& root, BinTreThrNode<T>*& prev)
    {
        BinTreThrNode<T>* cur = root;
        if (cur)
        {
            _PostOrderThearding(cur->_leftChild, prev);

            _PostOrderThearding(cur->_rightChild, prev);

            if (cur->_leftChild == NULL)
            {
                cur->_LTag = THREAD;
                cur->_leftChild = prev;
            }
            if (prev && prev->_rightChild == NULL && prev != cur)
            {
                prev->_rightChild = cur;
                prev->_RTag = THREAD;
            }
            prev = cur;
        }
    }

private:
    BinTreThrNode<T>* _root;
};

main.cpp

#include"BinaryTreeThreading.h"

void Test()
{
    int arr[] = { 1, 2, 3, '#', '#', '#', 4, 5 };
    BinaryTreeThread<int> bt(arr, 8);
    //bt.InOrderThearding();
    //bt.InOrder();
    /*bt.PrevOrderThearding();
    bt.PrevOrder();*/
    bt.PostOrderThearding();
    bt.PostOrder();
}
void Test1()
{
    int arr[] = { 1, 2, 3, '#', '#', 4,'#' ,'#', 5 ,6};
    BinaryTreeThread<int> bt(arr, 10);
    //bt.InOrderThearding();
    //bt.InOrder();
    /*bt.PrevOrderThearding();
    bt.PrevOrder();*/
    bt.PostOrderThearding();
    bt.PostOrder();
}
int main()
{
    Test();
    getchar();
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章