C++实现链式存储线索二叉树
一顆線索二叉樹:
根據下圖進行節點的創建:
代碼如下:
因為普通二叉樹有空指針域,所以我們可以利用這些空指針來線索化
1、二叉樹的線索化,實質上就是遍歷一棵二叉樹,在遍歷過程中,訪問節點的操作是檢查當前結點的左右指針域是否為空,如果為空,即將他們改為前驅節點或后繼節點的線索。為記錄前驅節點,定義pre為全局變量,始終指向當前結點的前驅節點。
定義一個全局變量指向線索二叉樹的前驅節點:
BiThrNode *pre;中序遍歷進行線索化:
void InThreading(BiThrTree p) {if (p){InThreading(p->lchild);if (!p->lchild){p->ltag = 1;p->lchild = pre;}if (!pre->rchild){pre->rtag = 1;pre->rchild = p;}pre = p;InThreading(p->rchild);} }根據下圖建立頭結點,線索化:
代碼如下:
對于中序線索二叉樹上的任意節點,尋找其中序的前驅節點,有以下兩種情況:
1、如果該節點的左標志域為1,那么其左指針所指向的節點便是它的前驅節點。
2、如果該節點的左標志為0,表明該節點有左孩子,根據中序遍歷的定義,它的前驅節點是以該節點的左孩子為根節點的子樹的最右節點,即沿著其左子樹的右指針鏈向下查找,當某節點的右標志域為1時,它就是所要找的前驅節點。
在中序線索二叉樹上查找任意節點的中序前驅節點:
BiThrNode *InPreNode(BiThrNode *p) {BiThrNode *pre;pre = p->lchild;if (p->ltag!=1){while(pre->rtag == 0){pre = pre->rchild;}}return pre; }對于中序線索二叉樹上的任意節點,尋找其中序的后繼節點,有以下兩種情況:
1、如果該節點的右標志域為1,那么其右指針所指向的節點便是它的后繼節點。
2、如果該節點的右標志為0,表明該節點有右孩子,根據中序遍歷的定義,它的后繼節點是以該節點的右孩子為根節點的子樹的最左節點,即沿著其右子樹的左指針鏈向下查找,當某節點的左標志域為1時,它就是所要找的后繼節點。
在中序線索二叉樹上查找任意節點的中序后繼節點:
BiThrNode *InpostNode(BiThrNode *p) {BiThrNode *post;post = p->rchild;if (p->rtag!=1){while(post->ltag==0){post = post->lchild;}}return post; }從最后一個節點根據前驅節點進行線索二叉樹的遍歷:
void InOrderPre(BiThrNode *head) {BiThrNode *p;p = head->rchild;//指向最后一個節點while(p != NULL && p!=head){cout<<p->data;p = InPreNode(p);} }從第一個節點根據后繼節點進行線索二叉樹的遍歷:
void InOrderPost(BiThrNode *head) {BiThrNode *p;p = head->lchild;while (p->ltag != 1) {p = p->lchild;}while (p != NULL && p != head) {cout << p->data;p = InPostNode(p);} }完整代碼如下:
#include <iostream> using namespace std; typedef char ElemType;typedef struct BiThrNode {//節點的創建ElemType data;int ltag, rtag;struct BiThrNode *lchild, *rchild; } BiThrNode, *BiThrTree;BiThrNode *pre;//定義一個全局變量指向線索二叉樹的前驅節點void InThreading(BiThrTree &p) {if (p) {InThreading(p->lchild);if (!p->lchild) {p->ltag = 1;p->lchild = pre;}if (!pre->rchild) {pre->rtag = 1;pre->rchild = p;}pre = p;InThreading(p->rchild);} }bool InOrderThr(BiThrTree &head, BiThrTree T) {head = new BiThrNode;if (head == NULL)return false;head->ltag = 0;head->rtag = 1;head->rchild = head;if (!T) {head->lchild = head;} else {head->lchild = T;pre = head;InThreading(T);pre->rchild = head;pre->rtag = 1;head->rchild = pre;}return true; }BiThrNode *InPreNode(BiThrNode *p) {BiThrNode *pre;pre = p->lchild;if (p->ltag != 1) {while (pre->rtag == 0) {pre = pre->rchild;}}return pre; }BiThrNode *InPostNode(BiThrNode *p) {BiThrNode *post;post = p->rchild;if (p->rtag != 1) {while (post->ltag == 0) {post = post->lchild;}}return post; }void InOrderPre(BiThrNode *head) {BiThrNode *p;p = head->rchild;//指向最后一個節點while (p != NULL && p != head) {cout << p->data;p = InPreNode(p);} }void InOrderPost(BiThrNode *head) {BiThrNode *p;p = head->lchild;while (p->ltag != 1) {p = p->lchild;}while (p != NULL && p != head) {cout << p->data;p = InPostNode(p);} }void CreateBiTree(BiThrTree &T) {//以先序遍歷的方式創建二叉樹char ch;cin >> ch;if (ch == '#')T = NULL;else {T = new BiThrNode;T->data = ch;T->ltag = 0;T->rtag = 0;CreateBiTree(T->lchild);CreateBiTree(T->rchild);} }int main() {BiThrTree T;BiThrNode *head;CreateBiTree(T);//以先序遍歷輸入if (InOrderThr(head, T))cout << "線索化完成" << endl;elsecout << "線索化失敗" << endl;cout<<"逆序輸出中序遍歷: ";InOrderPre(head);//逆序輸出中序遍歷cout << endl;cout<<"正序輸出中序遍歷: ";InOrderPost(head);//正序輸出中序遍歷return 0; }測試效果圖:
測試結果:
本文參考文章地址:
https://blog.csdn.net/g15827636417/article/details/52967949
總結
以上是生活随笔為你收集整理的C++实现链式存储线索二叉树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++实现邻接矩阵存储的图及dfs遍历
- 下一篇: 放血拔罐的好处和坏处是什么