C語言 數(shù)據(jù)結(jié)構(gòu)之中序二叉樹實(shí)例詳解
C語言數(shù)據(jù)結(jié)構(gòu) 中序二叉樹
前言:
線索二叉樹主要是為了解決查找結(jié)點(diǎn)的線性前驅(qū)與后繼不方便的難題。它只增加了兩個(gè)標(biāo)志性域,就可以充分利用沒有左或右孩子的結(jié)點(diǎn)的左右孩子的存儲(chǔ)空間來存放該結(jié)點(diǎn)的線性前驅(qū)結(jié)點(diǎn)與線性后繼結(jié)點(diǎn)。兩個(gè)標(biāo)志性域所占用的空間是極少的,所有充分利用了二叉鏈表中空閑存的儲(chǔ)空間。
要實(shí)現(xiàn)線索二叉樹,就必須定義二叉鏈表結(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu)如下(定義請(qǐng)看代碼):
left |
leftTag |
data |
rightTag |
right |
說明:
1. leftTag=false時(shí),表示left指向該結(jié)點(diǎn)的左孩子;
2. leftTag=true時(shí),表示left指向該結(jié)點(diǎn)的線性前驅(qū)結(jié)點(diǎn);
3. rightTag=false時(shí),表示right指向該結(jié)點(diǎn)的右孩子;
4. rightTag=true時(shí),表示right指向該結(jié)點(diǎn)的線性后繼結(jié)點(diǎn);
以二叉鏈表結(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu)所構(gòu)成的二叉鏈表作為二叉樹的存儲(chǔ)結(jié)構(gòu),叫做線索二叉鏈表;指向結(jié)點(diǎn)的線性前驅(qū)或者線性后繼結(jié)點(diǎn)的指針叫做線索;加上線索的二叉樹稱為線索二叉樹;對(duì)二叉樹以某種次序遍歷將其變?yōu)榫€索二叉樹的過程叫做線索化。
中序次序線索化二叉樹算法:
中序次序線索化是指用二叉鏈表結(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu)建立二叉樹的二叉鏈表,然后按照中序遍歷的方法訪問結(jié)點(diǎn)時(shí)建立線索;(具體看代碼)
檢索中序二叉樹某結(jié)點(diǎn)的線性前驅(qū)結(jié)點(diǎn)的算法:
1. 如果該結(jié)點(diǎn)的leftTag=true,那么left就是它的線性前驅(qū);
2. 如果該結(jié)點(diǎn)的leftTag=false,那么該結(jié)點(diǎn)左子樹最右邊的尾結(jié)點(diǎn)就是它的線性前驅(qū)點(diǎn);
(具體請(qǐng)看代碼)
檢索中序二叉樹某結(jié)點(diǎn)的線性后繼結(jié)點(diǎn)和算法:
1. 如果該結(jié)點(diǎn)的right=true,那么right就是它的線性后繼結(jié)點(diǎn);
2. 如果該結(jié)點(diǎn)的right=false,那么該結(jié)點(diǎn)右子樹最左邊的尾結(jié)點(diǎn)就是它的線性后繼結(jié)點(diǎn)
(具體請(qǐng)看代碼)
圖:后繼線索
圖:前驅(qū)線索
節(jié)點(diǎn)定義:
struct Node { int data; bool leftTag; bool rightTag; Node* left; Node* right; Node(int _data):data(_data),left(0),right(0),leftTag(false),rightTag(false){} };
類定義:
class BinaryTree { private: Node* root; private: Node* head; Node* pre; void makeThread(Node* node); public: void buildThread(); void traverseBySuccessor(); void traverseByPredecessor(); // helper methods private: static inline bool visit(Node* T) { if (T) { printf("data:%c, left:%c, right:%c\n", (char)T->data, (T->left!=0) ? (char)T->left->data : '#', (T->right!=0) ? (char)T->right->data : '#'); return true; } else return false; } };
方法定義:
void BinaryTree::makeThread(Node* node) { if (node!=NULL) { makeThread(node->left); if (pre!= NULL) { if (pre->right==NULL) // 如果前驅(qū)節(jié)點(diǎn)的右子樹為空, 那么把前驅(qū)節(jié)點(diǎn)的右子樹用作線索 { pre->rightTag = true; pre->right = node; } else pre->rightTag = false; } if (node->left==NULL) // 如果當(dāng)前結(jié)點(diǎn)的左子樹為空, 那么把當(dāng)前結(jié)點(diǎn)的左子樹用作線索 { node->leftTag = true; node->left = pre; } else node->leftTag = false; pre = node; makeThread(node->right); } } void BinaryTree::traverseBySuccessor() { Node* p = head->left; //first find the root node // 親測(cè)表明 如果不使用head啞節(jié)點(diǎn) 就要設(shè)三道卡, 防止p訪問到NULL, // 分別在主while處, 第二個(gè)visit處和下面的p=p->right處 while (p!=head) { while (!p->leftTag) p = p->left; visit(p); while (p->rightTag && p->right!=head) { p = p->right; visit(p); } p = p->right; } cout<<endl; } void BinaryTree::traverseByPredecessor() { Node* p = head->left; //first find the root node while (p!=head) { while (!p->rightTag) p = p->right; visit(p); if (p!=NULL) { while (p->leftTag && p->left!=head) { p = p->left; visit(p); } p = p->left; } } cout<<endl; } void BinaryTree::buildThread() { pre = NULL; head = new Node('@'); head->left = root; head->right = head; makeThread(root); // 經(jīng)過了makeThread過程之后, pre必然指向中序遍歷最晚的結(jié)點(diǎn). // 把pre的右子樹指向head, 就構(gòu)成了一個(gè)雙向循環(huán)鏈表 // pre->rightTag = 1; pre->right = head; pre = NULL; Node* p = root; /* * 在建立前驅(qū)線索的時(shí)候,最左邊的結(jié)點(diǎn)沒有和head結(jié)點(diǎn)連接。要在這里補(bǔ)上 */ while (p->left!=NULL) p = p->left; p->left = head; }
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
上一篇:C++中構(gòu)造函數(shù)與析構(gòu)函數(shù)的調(diào)用順序詳解
欄 目:C語言
下一篇:總結(jié)C/C++面試中可能會(huì)碰到的字符串指針題
本文標(biāo)題:C語言 數(shù)據(jù)結(jié)構(gòu)之中序二叉樹實(shí)例詳解
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/1805.html
您可能感興趣的文章
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用函數(shù)刪除字符
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)式函數(shù)庫
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)數(shù)怎么表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段函數(shù)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排序法函數(shù)
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段函數(shù)
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求階乘


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-11ajax實(shí)現(xiàn)頁面的局部加載