数据结构之线索二叉树
生活随笔
收集整理的這篇文章主要介紹了
数据结构之线索二叉树
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
線索二叉樹
- 思維導圖:
- 線索二叉數的引入:
- 線索二叉樹:
- 前序遍歷的線索二叉樹:
- 中序遍歷的線索二叉樹(常):
- 后序遍歷的線索二叉樹:
- 線索二叉樹的節點結構:
- 中序線索二叉樹代碼實現
- 中序線索二叉樹的構造:
- 中序線索二叉樹的遍歷以及找節點p的后序節點:
- 中序線索二叉樹的逆遍歷以及找節點p的前驅節點:
- 先序線索二叉樹代碼實現
- 先序線索二叉樹的構造:
- 先序線索二叉樹的遍歷以及找節點p的后序節點:
- 先序線索二叉樹的逆遍歷以及找節點p的前驅節點:
- 后序線索二叉樹代碼實現
- 后序線索二叉樹的構造:
- 后序線索二叉樹的遍歷以及找節點p的后序節點:
- 后序線索二叉樹的遍歷以及找節點p的前驅節點:
- 總結:
思維導圖:
線索二叉數的引入:
先來看這樣幾個問題:
1、普通二叉樹只有指向孩子節點的指針而沒有指向雙親節點的指針,這樣就會產生一個問題,無法方便快速的找到某一節點的雙親節點
2、當我們不知道根節點的指針,而是知道某一節點(非根節點)指針,就無法對二叉樹進行遍歷
我們知道,用鏈式存儲二叉樹時,會產生n+1個空指針,我們是否可以利用這些空指針而很方便的實現上述的兩種操作呢?
為此,我們引入線索二叉樹的概念。
線索二叉樹:
在實現一顆二叉樹時,會產生空指針,個數為n+1個,若節點無左子樹,將指針指向前驅節點;若無右子樹,將指針指向后繼節點,從而實現線索化,將加上線索的二叉樹稱為線索二叉樹。即:
1、若無左子樹,將指針指向前驅節點
2、若無右子樹,將指針指向后繼節點
前序遍歷的線索二叉樹:
ps: 由遍歷序列得到圖
中序遍歷的線索二叉樹(常):
后序遍歷的線索二叉樹:
線索二叉樹的節點結構:
例如:
中序線索二叉樹代碼實現
中序線索二叉樹的構造:
原理:
找前驅節點:
若左指針為線索,則其指向節點為前驅節點
若左指針為左孩子,則其左子樹的最右側節點為前驅節點
找后繼節點:
若右指針為線索,則其指向節點為后繼節點
若右指針為右孩子,則其右子樹的最左側節點為后繼節點
代碼實現:
void InThread(ThreadTree &p){if(p != NULL){InThread(p->lchild);visit(T);InThread(p->rchild);} } void visit(ThreadNode *p){if(p->lchild == NULL){p->lchild = pre;p->ltag = 1;}if(pre != NULL && pre->rchild == NULL){pre->rchild = p;pre->rtag = 1;}pre = p; }void CreateInThread(ThreadTree T){ThreadTree pre = NULL;if(T != NULL){InThread(T,pre);if(pre->rchild == NULL)pre->rtag = 1;} }中序線索二叉樹的遍歷以及找節點p的后序節點:
1、找到以p為根的子樹中,第一個被中序遍歷的節點
2、在中序線索二叉樹中找到節點p的后繼節點
3、實現對二叉樹的中序遍歷
中序線索二叉樹的逆遍歷以及找節點p的前驅節點:
//找到以p為根的子樹中,最后一個被中序遍歷的節點 ThreadNode *Lastnode(ThreadNode *p){//循環找到最左下節點,不一定是葉節點while(p->rtag == 0)p = p->rchild;return p; } //在中序線索二叉樹中找到節點p的前驅節點 ThreadNode *Prenode(ThreadNode *p){if(p->ltag == 0)return Lasttnode(p->lchild);elsereturn p->lchild; } //上面兩個函數實現了找到指定節點p的中序后繼,下面的函數實現對二叉樹的逆中序遍歷 //利用線索實現的惡非遞歸算法,空間復雜的o(1) void Revorder(ThreadNode *T){for(ThreadNode *p = Lastnode(T);p != NULL;p = Prenode(p))visit(p); }先序線索二叉樹代碼實現
先序線索二叉樹的構造:
代碼實現:
void PreThread(ThreadTree &p){if(p != NULL){visit(p);//當處理完p節點后會訪問p->lchild,但是經過visit(P)后p->lchild就會指向p的前驅節點,所以要對其進行判斷if(T->ltag == 0) //lchild不是前驅線索 PreThread(p->lchild);PreThread(p->rchild);} } void visit(ThreadNode *p){if(p->lchild == NULL){p->lchild = pre;p->ltag = 1;}if(pre != NULL && pre->rchild == NULL){pre->rchild = p;pre->rtag = 1;}pre = p; }void CreateInThread(ThreadTree T){ThreadTree pre = NULL;if(T != NULL){InThread(T,pre);if(pre->rchild == NULL)pre->rtag = 1;} }先序線索二叉樹的遍歷以及找節點p的后序節點:
先序線索二叉樹的逆遍歷以及找節點p的前驅節點:
ps:在只有指向孩子節點的節點結構中無法找到前驅
解決:增加一個指向雙親節點的指針
后序線索二叉樹代碼實現
后序線索二叉樹的構造:
代碼實現:
void PostThread(ThreadTree &p){if(p != NULL){PostThread(p->lchild);PostThread(p->rchild);visit(T);} } void visit(ThreadNode *p){if(p->lchild == NULL){p->lchild = pre;p->ltag = 1;}if(pre != NULL && pre->rchild == NULL){pre->rchild = p;pre->rtag = 1;}pre = p; }void CreateInThread(ThreadTree T){ThreadTree pre = NULL;if(T != NULL){InThread(T,pre);if(pre->rchild == NULL)pre->rtag = 1;} }后序線索二叉樹的遍歷以及找節點p的后序節點:
后序線索二叉樹的遍歷以及找節點p的前驅節點:
ps:在只有指向孩子節點的節點結構中無法找到前驅
解決:增加一個指向雙親節點的指針
總結:
總結
以上是生活随笔為你收集整理的数据结构之线索二叉树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android开发之高德API篇:2、高
- 下一篇: 简单的计时器实现(JFrame)