日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++ 实现线索二叉树

發(fā)布時間:2023/12/8 c/c++ 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ 实现线索二叉树 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

??本代碼主要參考了大話數(shù)據(jù)結(jié)構(gòu)的思想,由于其為c語言版,所以本人對其中一些函數(shù)進行了封裝,并增加了一些新的功能。

??由于本代碼的基本思想在大話數(shù)據(jù)結(jié)構(gòu)書中已經(jīng)說的很清楚了,所以此處就不再進行說明代碼原理。

??并且,在每個函數(shù)的后面,都寫了其作用,本人也盡可能地在必要的地方加了注釋。并且為了省事,用了shared_ptr。

??寫此代碼的目的是為了讓簡單線索二叉樹的代碼更加規(guī)范一點(很多c代碼都是用全局變量等不規(guī)范的形式)。此代碼在vs2019上能執(zhí)行,編譯器需要支持c++11以上。

文章目錄

  • 一、線索二叉樹節(jié)點類~
  • 二、線索二叉樹類~
  • 三、完整頭文件~
  • 四、測試cpp~

一、線索二叉樹節(jié)點類~

using std::cout; using std::endl; using std::shared_ptr; using std::make_shared;namespace {enum class PointerTag{Linked, Thread}; }template<typename T = int> struct ThreadNode { public:using ThreadNodePtr = shared_ptr<ThreadNode<T>>;public:T _data;ThreadNodePtr _lchild;ThreadNodePtr _rchild;PointerTag _lTag;/*左右標簽*/PointerTag _rTag;ThreadNode(const T& data) :_data(data),_lchild(nullptr),_rchild(nullptr),_lTag(PointerTag::Linked),_rTag(PointerTag::Linked) {}ThreadNode(const ThreadNode& other):_data(other._data),_lchild(other._lchild),_rchild(other._rchild),_lTag(other._lTag),_rTag(other._rTag){} };

二、線索二叉樹類~

template<typename T = int>class ThreadTree {public:using ThreadNodePtr = shared_ptr<ThreadNode<T>>;private:ThreadNodePtr _root;/*根節(jié)點*/ThreadNodePtr _hot;//剛被訪問過的節(jié)點ThreadNodePtr _head;//線索二叉樹頭節(jié)點哨兵public:ThreadTree() :_root(nullptr), _hot(nullptr), _head(nullptr) {}ThreadTree(T* PrevOrder, T* InOrder, const int& num) :_hot(nullptr), _head(nullptr) {//以前序和中序序列創(chuàng)建二叉樹_root = buildTree(PrevOrder, InOrder, num);}void InThread();//從根節(jié)點開始,線索化二叉樹void InOrderTrav_Thread()const;//以線索二叉樹的方式進行遍歷private:ThreadNodePtr buildTree(T* PrevOrder, T* InOrder, const int& num);//以前序和中序序列創(chuàng)建二叉樹void InThreading(ThreadNodePtr); /*對根節(jié)點進行中序線索化*/};

三、完整頭文件~

#pragma once using std::cout; using std::endl; using std::shared_ptr; using std::make_shared;namespace my_thread_tree {namespace {enum class PointerTag{Linked, Thread};}template<typename T = int>struct ThreadNode {public:using ThreadNodePtr = shared_ptr<ThreadNode<T>>;public:T _data;ThreadNodePtr _lchild;ThreadNodePtr _rchild;PointerTag _lTag;/*左右標簽*/PointerTag _rTag;ThreadNode(const T& data) :_data(data),_lchild(nullptr),_rchild(nullptr),_lTag(PointerTag::Linked),_rTag(PointerTag::Linked) {}ThreadNode(const ThreadNode& other):_data(other._data),_lchild(other._lchild),_rchild(other._rchild),_lTag(other._lTag),_rTag(other._rTag){}};template<typename T = int>class ThreadTree {public:using ThreadNodePtr = shared_ptr<ThreadNode<T>>;private:ThreadNodePtr _root;/*根節(jié)點*/ThreadNodePtr _hot;//剛被訪問過的節(jié)點ThreadNodePtr _head;//線索二叉樹頭節(jié)點哨兵public:ThreadTree() :_root(nullptr), _hot(nullptr), _head(nullptr) {}ThreadTree(T* PrevOrder, T* InOrder, const int& num) :_hot(nullptr), _head(nullptr) {//以前序和中序序列創(chuàng)建二叉樹_root = buildTree(PrevOrder, InOrder, num);}void InThread();//從根節(jié)點開始,線索化二叉樹void InOrderTrav_Thread()const;//以線索二叉樹的方式進行遍歷private:ThreadNodePtr buildTree(T* PrevOrder, T* InOrder, const int& num);//以前序和中序序列創(chuàng)建二叉樹void InThreading(ThreadNodePtr); /*對根節(jié)點進行中序線索化*/};template<typename T>void ThreadTree<T>::InOrderTrav_Thread()const{ThreadNodePtr p = _root;//指向根節(jié)點while (p != _head) {//當沒有遍歷到頭節(jié)點哨兵時while (p->_lTag == PointerTag::Linked)//一直往左,直到左孩子記錄的為前驅(qū)而不是左孩子時p = p->_lchild;cout << "數(shù)據(jù)為:\t" << p->_data << "\t引用計數(shù)為:\t" << p.use_count() << endl;while (p->_rTag == PointerTag::Thread && p->_rchild != _head) {//遍歷到直到p的右孩子為右孩子而不是后繼時p = p->_rchild;cout << "數(shù)據(jù)為:\t" << p->_data << "\t引用計數(shù)為:\t" << p.use_count() << endl;}p = p->_rchild;//p進入右子樹根}cout << endl;}template<typename T>shared_ptr<ThreadNode<T>> ThreadTree<T>::buildTree(T* PrevOrder, T* InOrder, const int& num){if (PrevOrder == nullptr || InOrder == nullptr || num <= 0){return nullptr;}ThreadNodePtr root =make_shared<ThreadNode<T>>(PrevOrder[0]);// 前序遍歷的第一個數(shù)據(jù)就是根節(jié)點數(shù)據(jù) //中序遍歷,根節(jié)點左為左子樹,右為右子樹 int rootposition = -1;for (int i = 0; i < num; i++){if (InOrder[i] == root->_data){rootposition = i;}}if (rootposition == -1)return nullptr;//重建左子樹(根節(jié)點)遞歸 int LeftNum = rootposition;T* PrevOrderLeft = PrevOrder + 1; //前序第二個即為根節(jié)點的左子樹 T* InOrderLeft = InOrder; //中序第一個 即為其左子樹。 root->_lchild = buildTree(PrevOrderLeft, InOrderLeft, LeftNum);//重建右子樹(根節(jié)點)遞歸 int RightNum = num - LeftNum - 1;//右半邊子樹T* PrevOrderRight = PrevOrder + 1 + LeftNum;T* InOrderRight = InOrder + LeftNum + 1;root->_rchild = buildTree(PrevOrderRight, InOrderRight, RightNum);return root;}template<typename T>void ThreadTree<T>::InThreading(ThreadNodePtr p){if (p != nullptr) {InThreading(p->_lchild);if (p->_lchild == nullptr) {p->_lTag = PointerTag::Thread;p->_lchild = _hot;//p的左孩子設為前驅(qū)}if (_hot != nullptr && _hot->_rchild == nullptr) {//前驅(qū)的右孩子為空時_hot->_rTag = PointerTag::Thread;_hot->_rchild = p;//將前驅(qū)的右孩子設為p}_hot = p;InThreading(p->_rchild);}}template<typename T>void ThreadTree<T>::InThread() {//從根節(jié)點開始,線索化二叉樹if (_root == nullptr)return;//頭哨兵節(jié)點初始化_head = make_shared<ThreadNode<T>>(0);//反正不會訪問這個,所以初值不妨就設成0_head->_rTag = PointerTag::Thread;_head->_lchild = _root;_head->_rchild = _head;_hot = _head;//將_hot設定為_headInThreading(_root);//線索化二叉樹//遍歷之后,_hot必然為中序遍歷最右邊那個節(jié)點_hot->_rTag = PointerTag::Thread;_hot->_rchild = _head;//就將頭哨兵作為_hot的右孩子_head->_rchild = _hot;//并且將_hot作為頭哨兵的右孩子}}//namespace my_thread_tree

四、測試cpp~

#include <iostream> #include "ThreadTree.h" using namespace std; using namespace my_thread_tree;int main() {//int a[] = { 3,1,0,2,5,4,6 };//int b[] = { 0,1,2,3,4,5,6 };char a[] = { 'A','B','D','H','I','E','J','C','F','G'};char b[] = { 'H','D','I','B','J','E','A','F','C','G' };ThreadTree<char> TT(a, b, 10);//傳參時傳入兩個數(shù)組,分別為樹的前序和中序遍歷序列TT.InThread();TT.InOrderTrav_Thread();return 0; }

引用計數(shù)這個可以忽略,主要是玩下看有多少個指針指向這個對象

數(shù)據(jù)為: H 引用計數(shù)為: 2 數(shù)據(jù)為: D 引用計數(shù)為: 4 數(shù)據(jù)為: I 引用計數(shù)為: 2 數(shù)據(jù)為: B 引用計數(shù)為: 4 數(shù)據(jù)為: J 引用計數(shù)為: 2 數(shù)據(jù)為: E 引用計數(shù)為: 3 數(shù)據(jù)為: A 引用計數(shù)為: 5 數(shù)據(jù)為: F 引用計數(shù)為: 2 數(shù)據(jù)為: C 引用計數(shù)為: 4 數(shù)據(jù)為: G 引用計數(shù)為: 4

總結(jié)

以上是生活随笔為你收集整理的c++ 实现线索二叉树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美视频在线看 | 黄色片视频免费在线观看 | 亚洲麻豆av | 国产老妇伦国产熟女老妇视频 | 欧美老熟妇乱大交xxxxx | 欧美激情一二区 | 国产亚洲欧美一区二区 | 国产二级片 | 91丨九色丨蝌蚪丨丝袜 | 精品免费囯产一区二区三区 | 奇米影视盒| 久久久www免费人成人片 | av片大全 | 精品毛片一区二区三区 | 狠狠天天 | 欧美一区二区三区久久综合 | 中文字幕欧美日韩 | 国产在线视频第一页 | av网址在线免费观看 | 狂野少女电影在线观看国语版免费 | 少妇久久久久久久 | 午夜av在线 | 四虎av在线 | 亚洲精品一区二区三区四区乱码 | 精品久久久久一区二区国产 | 少妇性生活视频 | 91精品国产综合久 | 夜夜爽妓女8888视频免费观看 | 亚洲aa | www成人 | 都市激情亚洲色图 | 日本电影成人 | 波多野结衣一级 | 免费高清欧美大片在线观看 | 西西毛片 | 久久免费视频一区 | 亚洲综合一区二区 | 国产精品久久久久久久妇 | 欧美精品hd | 91深夜福利 | 欧美图片第一页 | 日韩高清片 | 国产在视频线精品视频 | 韩国一级片在线观看 | www..com黄色| 国产黄在线 | 综合激情亚洲 | 日韩午夜精品视频 | 国产伦精品一区二区三区视频黑人 | 免费在线看黄色片 | 深夜av| jizz日本视频 | 久操视频在线观看 | 亚洲日本免费 | 成年性生交大片免费看 | 国产精品刺激 | 久久精品国产亚洲AV成人雅虎 | 久久av资源网 | 麻豆91网站| 91蜜桃婷婷狠狠久久综合9色 | 无码人妻一区二区三区在线 | 中文字幕日韩一区二区三区不卡 | 中文字幕在线观看不卡 | 精品在线免费视频 | 中文字幕欧美专区 | 久久久久18 | 免费成人美女女 | 欧美一区二区三区在线播放 | 农民人伦一区二区三区 | 中国一级大黄大黄大色毛片 | 精品国产乱码久久久久久浪潮 | 成人观看视频 | 久草热在线观看 | 免费成人91 | 日韩一级免费视频 | 天天操欧美 | 色天天av| 少妇精品偷拍高潮白浆 | 亚洲精品无码不卡在线播he | 午夜视频在线观看一区二区 | 2022精品国偷自产免费观看 | 亚洲国产大片 | 一级片国产 | 久久国产美女视频 | 成人免费网站在线观看 | 亚洲综合欧美日韩 | 丁香啪啪综合成人亚洲 | 4438五月天| 国产精品5区 | 91精品国产一区二区 | 在线视频麻豆 | 国产草草影院ccyycom | 国产成人无码www免费视频播放 | 奇米久久久 | 黄色大片久久 | 在线视频资源 | 天天操天天碰 | 三级网站在线 | 中文av网|