二叉樹(二)線索二叉樹

来源:https://www.cnblogs.com/teternity/archive/2020/01/31/12246785.html
-Advertisement-
Play Games

二叉樹創建 先序線索、中序線索,通過線索進行的 先序遍歷、中序遍歷。 main.cpp: #include <iostream> #include <queue> #include "ThreadedBinaryTree.h" using namespace std; int main() { qu ...


二叉樹創建 先序線索、中序線索,通過線索進行的 先序遍歷、中序遍歷。

 

main.cpp:

#include <iostream>
#include <queue>
#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 <queue>
#include <stack>
template<typename _Ty>
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<typename _Ty>
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<typename _Ty>
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<typename _Ty>
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<typename _Ty>
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<typename _Ty>
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<typename _Ty>
void ThreadedBinaryTree<_Ty>::levelTraversal(Node* _node) const
{
    if (_node == nullptr) return;
    std::queue<Node*> 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<typename _Ty>
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<typename _Ty>
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<typename _Ty>
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<typename _Ty>
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<typename _Ty>
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__

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 選擇器權值: 標簽選擇器:1 類選擇器和偽類選擇器:10 ID選擇器:100 通配符選擇器:0 行內樣式:1000 !important 在一定條件下,優先順序最高 常用的css樣式命名 頁面結構頁頭:header頁面主體:main頁尾:footer內容:content/container容器: co ...
  • function a(){} 和 var a = function(){}的區別: 學習做浮窗,看到別人的代碼里有: window.onresize = function(){ chroX = document.documentElement.clientWidth;//yemian整個的高寬 ch ...
  • 本章介紹UML建模元素 1:Stereotype-也被稱為類型、構造型 UML里的元素擴展,簡單來說其功能就是在已有的類型上添加一些標記,類似於打個戳,從而生成新的東西。 簡單的說加一句話來更加清楚準確描述這個類。 2:Actor(主角、參與者)-是在系統之外與系統交互的某人或某事物,在建模過程中處 ...
  • 萬變不離其宗,不管是Java還是C++,凡是面向對象的編程語言,在設計上,儘管表現形式可能有所不同,但是其實質和所需遵守的原則都是一致的。本文便是帶領讀者去深入理解設計模式中的六大原則,以期幫助讀者做出更好的設計。 ...
  • 分支管理 軟體的版本控制以及分支管理貫穿於整個軟體產品的生命周期,日常的項目管理對於開發團隊能否有節奏且順利的交付軟體也很重要。本分支管理和版本控制規範主要分為3個部分,即分支管理規範、版本號規範、需求與代碼關聯。其中,將闡述不同的分支管理模型,以及它們的優缺點和使用的場景;描述版本號控制方式——語 ...
  • 第一次用maven創建項目的時候,因為本地倉庫中沒有jar包,需要從中央倉庫下載,所以會比較慢,因為從中央倉庫下載預設使用的國外的鏡像下載,速度比較慢,我們可以把鏡像修改為從阿裡雲下載,這樣比較快,方法,打開maven在本地的位置,找到conf文件夾下的setting,xml打開,在mirrors標... ...
  • 學完maven後,可以創建maven的javaweb工程,在創建完成後還需要一些配置,下麵來說下具體步驟,在這裡我創建的是一個模塊,創建web項目的方式和創建模塊一樣 ...
  • MyBatis Plus是一個 MyBatis的增強工具,在 MyBatis 的基礎上只做增強不做改變,使用MyBatis Plus時,不會影響原來Mybatis方式的使用。 SpringBoot+MyBatis Plus環境搭建 SQL腳本: CREATE TABLE ( int(11) NOT ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...