二叉樹之 線索二叉樹

2021-09-18 05:48:26 字數 3125 閱讀 3303

二叉樹是一種非線性結構,遍歷二叉樹幾乎都是通過遞迴或者用棧輔助實現非遞迴的遍歷。用二叉樹作為儲存結構時,取到乙個節點,只能獲取節點的左孩子和右孩子,不能直接得到節點的任一遍歷序列的前驅或者後繼。

為了儲存這種在遍歷中需要的資訊,我們利用二叉樹中指向左右子樹的空指標來存放節點的前驅和後繼資訊

對於n個結點的二叉樹,在二叉鏈儲存結構中有n+1個空鏈域,利用這些空鏈域存放在某種遍歷次序下該結點的前驅結點和後繼結點的指標,這些指標稱為線索,加上線索的二叉樹稱為線索二叉樹。

二叉樹的遍歷本質上是將乙個複雜的非線性結構轉換為線性結構,使每個結點都有了唯一前驅和後繼(第乙個結點無前驅,最後乙個結點無後繼)。對於二叉樹的乙個結點,查詢其左右子女是方便的,其前驅後繼只有在遍歷中得到。為了容易找到前驅和後繼,有兩種方法。一是在結點結構中增加向前和向後的指標fwd和bkd,這種方法增加了儲存開銷,不可取;二是利用二叉樹的空鏈指標。現將二叉樹的結點結構重新定義如下:

//#include

#include

#include

#include

#include

#include

using namespace std ;

typedef

long

long ll;

#define maxn 100005

#define inf 0x3f3f3f3f

#define mall (bithrnode *)malloc(sizeof(bithrnode));

typedef

struct bithrnode

bithrnode,

*bitree;

bitree pre =

null

;//pre為空

ltag, rtag分別為該結點的直接前驅和直接後繼,當其為1時說明有前驅或者後繼的線索化,而當其為0時,則代表該結點有左兒子或右兒子。

建立線索二叉樹,或者說對二叉樹線索化,實質上就是遍歷一棵二叉樹。在遍歷過程中,訪問結點的操作是檢查當前的左,右指標域是否為空,將它們改為指向前驅結點或後續結點的線索。為實現這一過程,設指標pre始終指向剛剛訪問的結點,即若指標p指向當前結點,則pre指向它的前驅,以便設線索。

另外,在對一顆二叉樹加線索時,必須首先申請乙個頭結點,建立頭結點與二叉樹的根結點的指向關係,對二叉樹線索化後,還需建立最後乙個結點與頭結點之間的線索。

下面是建立中序二叉樹的遞迴演算法,其中pre為全域性變數。

首先是先序遍歷下建立一顆二叉樹:

bitree creatbitree

(bitree &t)

return t;

}

現在我們開始線索化二叉樹:
void

inthreeding

(bitree p)

else

p->ltag =0;

if(!pre->rchild)

//同理

else

pre->rtag =0;

pre = p;

inthreeding

(p->rchild)

;//右子樹遞迴線索化}}

// 建立頭結點,形成迴圈鍊錶

void

inorderthreading

(bitree &thrt, bitree t)

//thrt指向頭結點

}

中序遍歷線索二叉樹:
void

cout

(bitree t)

p = p->rchild;

//轉向p的右子樹。

} cout <<

'\n'

;}

(先序以後寫趴。。。。)

完整版:

//#include

#include

#include

#include

#include

#include

using namespace std ;

typedef

long

long ll;

#define maxn 100005

#define inf 0x3f3f3f3f

#define mall (bithrnode *)malloc(sizeof(bithrnode));

typedef

struct bithrnode

bithrnode,

*bitree;

bitree pre =

null

;void

first

(bitree t)

}void

middle

(bitree t)

}void

end(bitree t)

}bitree creatbitree

(bitree &t)

return t;

}void

inthreeding

(bitree p)

else

p->ltag =0;

if(!pre->rchild)

//同理

else

pre->rtag =0;

pre = p;

inthreeding

(p->rchild)

;//右子樹遞迴線索化}}

void

inorderthreading

(bitree &thrt, bitree t)

//thrt指向頭結點

}void

cout

(bitree t)

p = p->rchild;

//轉向p的右子樹。

} cout <<

'\n';}

void

copy

(bitree t, bitree &newt)

else

}int

depth

(bitree t)

}int

nodecount

(bitree t)

intyezi

(bitree t)

intmain()

複習二叉樹之線索二叉樹

include 線索二叉樹是在遍歷的過程中線索化 typedef struct bithrnodebithrnode,bithrtree bithrtree pre 全域性變數 建立二叉鍊錶 先序遍歷建立 關鍵在於 表明空樹 void createbitree bithrtree a else 為什...

樹 二叉樹 線索二叉樹

一 線索二叉樹 1 什麼是線索化 將二叉樹以某種次序將其遍歷,得到線性序列,就是將非線性結構進行線索化。線索化的優點就是可以很快地得到前驅或後繼。如果儲存線索化的線性序列 儲存二叉樹地線索化序列的其中一種方法就是在結點上加兩個指標,乙個指向前驅乙個指向後繼,這樣的缺點就是儲存密度大大降低。另一種方法...

線索二叉樹

當用二叉鍊錶作為二叉樹的儲存結構時,因為每個結點中只有指向其左 右兒子結點的指標,所以從任一結點出發只能直接找到該結點的左 右兒子。在一般情況下靠它無法直接找到該結點在某種遍歷序下的前驅和後繼結點。如果在每個結點中增加指向其前驅和後繼結點的指標,將降低儲存空間的效率。我們可以證明 在n個結點的二叉鍊...