二叉树(二)线索二叉树

二叉树创建 先序线索、中序线索,通过线索进行的 先序遍历、中序遍历。

 

main.cpp:

#include 
#include 
#include "ThreadedBinaryTree.h"
using namespace std;

int main()
{
    queue<char> qu({ 'a','b','c',0,0,'d','e',0,0,'f','g',0,0,0,'h','i',0,0,'j',0,0 });
    ThreadedBinaryTree<char> thBinTree(0, qu);

    cout << "preorderTraversal:\n\t";
    thBinTree.preorderTraversal();
    cout << "\n\npreorderTraversalByThread:\n\t";
    thBinTree.preorderTraversalByThread();
    cout << "\n\ninorderTraversal:\n\t";
    thBinTree.inorderTraversal();
    cout << "\n\ninorderTraversalByThread:\n\t";
    thBinTree.inorderTraversalByThread();
    cout << "\n\npostorderTraversal:\n\t";
    thBinTree.postorderTraversal();
    cout << "\n\nlevelTraversal:\n\t";
    thBinTree.levelTraversal();
    cout << endl;

    return 0;
}

 

 

ThreadedBinaryTree.h:

#pragma once
#ifndef __THREADEDBINARYTREE_H__
#define __THREADEDBINARYTREE_H__


#include 
#include 
template
class ThreadedBinaryTree
{
private:
    enum class Tag :bool { LINK = 0, THREAD };
    struct Node
    {
        _Ty data;
        Tag Ltag = Tag::LINK;
        Tag Rtag = Tag::LINK;
        Node* left = nullptr;
        Node* right = nullptr;
        Node(const _Ty& _data) :data(_data) {}
    };

public:
    enum class ThreadType { NONE = 0, INORDER, PREORDER };

public:
    ThreadedBinaryTree(const _Ty& _val) :nullVal(_val) {}
    ThreadedBinaryTree(const _Ty& _val, std::queue<_Ty>& _qu) :nullVal(_val) { creatTree(_qu, root); }
    ~ThreadedBinaryTree() { clear(root); }
    void clear() { head = nullptr; threadType = ThreadType::NONE; clear(root); }
    size_t size() const { return size_n; }
    void setNullValue(const _Ty& _val) { nullVal = _val; }
    void creatTree(std::queue<_Ty>& _qu) { if (root != nullptr) clear(root); creatTree(_qu, root); }
    void preorderTraversal() const { preorderTraversal(root); }
    void inorderTraversal() const { inorderTraversal(root); }
    void postorderTraversal() const { postorderTraversal(root); }
    void levelTraversal() const { levelTraversal(root); }
    void creatThread(ThreadType);
    void inorderTraversalByThread();
    void preorderTraversalByThread();

private:
    void creatTree(std::queue<_Ty>&, Node*&);
    void clear(Node*&);
    void preorderTraversal(Node*) const;
    void inorderTraversal(Node*) const;
    void postorderTraversal(Node*) const;
    void levelTraversal(Node*) const;
    void creatInorderThread(Node*, Node*& _pre);
    void creatPreorderThread(Node*, Node*& _pre);

private:
    _Ty nullVal;
    size_t size_n = 0;
    Node* root = nullptr;
    Node* head = nullptr;
    ThreadType threadType = ThreadType::NONE;
};

template
void ThreadedBinaryTree<_Ty>::creatTree(std::queue<_Ty>& _qu, Node*& _node)
{
    if (_qu.empty()) return;
    if (_qu.front() == nullVal)
    {
        _qu.pop();
        return;
    }
    _node = new Node(_qu.front());
    _qu.pop();
    ++size_n;
    creatTree(_qu, _node->left);
    creatTree(_qu, _node->right);
}

template
void ThreadedBinaryTree<_Ty>::clear(Node*& _node)
{
    if (_node == nullptr) return;
    if (_node->left != nullptr && _node->Ltag == Tag::LINK)
        clear(_node->left);
    if (_node->right != nullptr && _node->Rtag == Tag::LINK)
        clear(_node->right);
    delete _node;
    _node = nullptr;
    --size_n;
}

template
void ThreadedBinaryTree<_Ty>::preorderTraversal(Node* _node) const
{
    if (_node == nullptr) return;
    std::cout << _node->data << " ";
    if (_node->left != nullptr && _node->Ltag == Tag::LINK)
        preorderTraversal(_node->left);
    if (_node->right != nullptr && _node->Rtag == Tag::LINK)
        preorderTraversal(_node->right);
}

template
void ThreadedBinaryTree<_Ty>::inorderTraversal(Node* _node) const
{
    if (_node == nullptr) return;
    if (_node->left != nullptr && _node->Ltag == Tag::LINK)
        inorderTraversal(_node->left);
    std::cout << _node->data << " ";
    if (_node->right != nullptr && _node->Rtag == Tag::LINK)
        inorderTraversal(_node->right);
}

template
void ThreadedBinaryTree<_Ty>::postorderTraversal(Node* _node) const
{
    if (_node == nullptr) return;
    if (_node->left != nullptr && _node->Ltag == Tag::LINK)
        postorderTraversal(_node->left);
    if (_node->right != nullptr && _node->Rtag == Tag::LINK)
        postorderTraversal(_node->right);
    std::cout << _node->data << " ";
}

template
void ThreadedBinaryTree<_Ty>::levelTraversal(Node* _node) const
{
    if (_node == nullptr) return;
    std::queue nodePointers;
    nodePointers.push(_node);
    while (!nodePointers.empty())
    {
        Node* cur = nodePointers.front();
        std::cout << cur->data << " ";
        if (cur->left != nullptr && cur->Ltag == Tag::LINK) nodePointers.push(cur->left);
        if (cur->right != nullptr && cur->Rtag == Tag::LINK) nodePointers.push(cur->right);
        nodePointers.pop();
    }
}

template
void ThreadedBinaryTree<_Ty>::creatInorderThread(Node* _node, Node*& _pre)
{
    if (_node == nullptr) return;
    if (_node->Ltag == Tag::LINK)
        creatInorderThread(_node->left, _pre);
    if (_node->left == nullptr || _node->Ltag == Tag::THREAD)
    {
        _node->Ltag = Tag::THREAD;
        _node->left = _pre;
    }
    if (_pre != nullptr && (_pre->right == nullptr || _pre->Rtag == Tag::THREAD))
    {
        _pre->Rtag = Tag::THREAD;
        _pre->right = _node;
    }
    _pre = _node;
    if (_node->Rtag == Tag::LINK)
        creatInorderThread(_node->right, _pre);
}

template
void ThreadedBinaryTree<_Ty>::creatPreorderThread(Node* _node, Node*& _pre)
{
    if (_node == nullptr) return;
    if (_node->left == nullptr || _node->Ltag == Tag::THREAD)
    {
        _node->Ltag = Tag::THREAD;
        _node->left = _pre;
    }
    if (_pre != nullptr && (_pre->right == nullptr || _pre->Rtag == Tag::THREAD))
    {
        _pre->Rtag = Tag::THREAD;
        _pre->right = _node;
    }
    _pre = _node;
    if (_node->Ltag == Tag::LINK)
        creatPreorderThread(_node->left, _pre);
    if (_node->Rtag == Tag::LINK)
        creatPreorderThread(_node->right, _pre);
}

template
void ThreadedBinaryTree<_Ty>::creatThread(ThreadType _type)
{
    if (root == nullptr || _type == threadType) return;
    if (_type != ThreadType::INORDER && _type != ThreadType::PREORDER)
    {
        delete head;
        head = nullptr;
        threadType = _type;
        return;
    }
    if (head != nullptr && _type != threadType) delete head;
    head = new Node(static_cast<_Ty>(0));
    head->left = root;
    threadType = _type;
    Node* temp = nullptr;
    switch (threadType)
    {
    case ThreadType::INORDER:
        creatInorderThread(root, temp);
        break;
    case ThreadType::PREORDER:
        creatPreorderThread(root, temp);
        break;
    }
    head->right = temp;
}

template
void ThreadedBinaryTree<_Ty>::inorderTraversalByThread()
{
    if (root != nullptr) creatThread(ThreadType::INORDER);
    if (head == nullptr) return;
    Node* temp = head->left;
    while (temp != nullptr)
    {
        while (temp->Ltag == Tag::LINK) temp = temp->left;
        std::cout << temp->data << " ";
        while (temp != nullptr && temp->Rtag == Tag::THREAD)
        {
            temp = temp->right;
            if (temp != nullptr)
                std::cout << temp->data << " ";
        }
        if (temp != nullptr)
            temp = temp->right;
    }
}

template
void ThreadedBinaryTree<_Ty>::preorderTraversalByThread()
{
    if (root != nullptr) creatThread(ThreadType::PREORDER);
    if (head == nullptr) return;
    Node* temp = head->left;
    while (temp != nullptr)
    {
        std::cout << temp->data << " ";
        if (temp->Ltag == Tag::LINK)
            temp = temp->left;
        else
            temp = temp->right;
    }
}


#endif // !__THREADEDBINARYTREE_H__

 

你可能感兴趣的:(二叉树(二)线索二叉树)