1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
ADT BinaryTree{
數據對象D:D是具備相同特性的數據元素的集合。
數據關係R:
若D=Φ,則R=Φ,稱BinaryTree爲空二叉樹;
若D≠Φ,則R={H},H是以下二元關係;
(1)在D中存在唯一的稱爲根的數據元素root,它在關係H下無前驅;
(2)若D-{root}≠Φ,則存在D-{root}={D1,Dr},且D1∩Dr =Φ;
(3)若D1≠Φ,則D1中存在唯一的元素x1,<root,x1>∈H,且存在D1上的關係H1 ⊆H;若Dr≠Φ,則Dr中存在唯一的元素xr,<root,xr>∈H,且存在Dr上的關係Hr ⊆H;H={<root,x1>,<root,xr>,H1,Hr};
(4)(D1,{H1})是一棵符合本定義的二叉樹,稱爲根的左子樹;(Dr,{Hr})是一棵符合本定義的二叉樹,稱爲根的右子樹。
基本操做:
InitBiTree( &T )
操做結果:構造空二叉樹T。
DestroyBiTree( &T )
初始條件:二叉樹T已存在。
操做結果:銷燬二叉樹T。
CreateBiTree( &T, definition )
初始條件:definition給出二叉樹T的定義。
操做結果:按definiton構造二叉樹T。
ClearBiTree( &T )
初始條件:二叉樹T存在。
操做結果:將二叉樹T清爲空樹。
BiTreeEmpty( T )
初始條件:二叉樹T存在。
操做結果:若T爲空二叉樹,則返回TRUE,不然返回FALSE。
BiTreeDepth( T )
初始條件:二叉樹T存在。
操做結果:返回T的深度。
Root( T )
初始條件:二叉樹T存在。
操做結果:返回T的根。
Value( T, e )
初始條件:二叉樹T存在,e是T中某個結點。
操做結果:返回e的值。
Assign( T, &e, value )
初始條件:二叉樹T存在,e是T中某個結點。
操做結果:結點e賦值爲value。
Parent( T, e )
初始條件:二叉樹T存在,e是T中某個結點。
操做結果:若e是T的非根結點,則返回它的雙親,不然返回「空」。
LeftChild( T, e )
初始條件:二叉樹T存在,e是T中某個結點。
操做結果:返回e的左孩子。若e無左孩子,則返回「空」。
RightChild( T, e )
初始條件:二叉樹T存在,e是T中某個結點。
操做結果:返回e的右孩子。若e無右孩子,則返回「空」。
LeftSibling( T, e )
初始條件:二叉樹T存在,e是T中某個結點。
操做結果:返回e的左兄弟。若e是T的左孩子或無左兄弟,則返回「空」。
RightSibling( T, e )
初始條件:二叉樹T存在,e是T中某個結點。
操做結果:返回e的右兄弟。若e是T的右孩子或無右兄弟,則返回「空」。
InsertChild( T, p, LR, c )
初始條件:二叉樹T存在,p指向T中某個結點,LR爲0或1,非空二叉樹c與T不相交且右子樹爲空。
操做結果:根據LR爲0或1,插入c爲T中p所指結點的左或右子樹。p所指結點的原有左或右子樹則成爲c的右子樹。
DeleteChild( T, p, LR )
初始條件:二叉樹T存在,p指向T中某個結點,LR爲0或1。
操做結果:根據LR爲0或1,刪除T中p所指結點的左或右子樹。
PreOrderTraverse( T, visit() )
初始條件:二叉樹T存在,Visit是對結點操做的應用函數。
操做結果:先序遍歷T,對每一個結點調用函數Visit一次且僅一次。一旦visit()失敗,則操做失敗。
InOrderTraverse( T, visit() )
初始條件:二叉樹T存在,Visit是對結點操做的應用函數。
操做結果:中序遍歷T,對每一個結點調用函數Visit一次且僅一次。一旦visit()失敗,則操做失敗。
PostOrderTraverse( T, visit() )
初始條件:二叉樹T存在,Visit是對結點操做的應用函數。
操做結果:後序遍歷T,對每一個結點調用函數Visit一次且僅一次。一旦visit()失敗,則操做失敗。
LevelOrderTraverse( T, visit() )
初始條件:二叉樹T存在,Visit是對結點操做的應用函數。
操做結果:層次遍歷T,對每一個結點調用函數Visit一次且僅一次。一旦visit()失敗,則操做失敗。
}ADT BinaryTree
|
二叉樹的結點結構體:函數
1
2
3
4
|
typedef
struct
{
TElemType data;
struct
BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
|
1.二叉樹的建立:spa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/*******************************************/
/* 按照前序遍歷創建二叉樹 */
/*******************************************/
Status CreateBiTree(BiTree &T)
{
//按先序次序輸入二叉樹中結點的值(一個字符),
//空格字符表示空樹,構造二叉鏈表表示的二叉樹T。
char
ch;
ch =
getchar
();
//scanf("%c",&ch);
if
(ch ==
' '
)
T = NULL;
else
{
if
(!(T = (BiTNode*)
malloc
(
sizeof
(BiTNode))))
exit
(OVERFLOW);
T->data = ch;
//生成根結點
CreateBiTree(T->lchild);
//構造左子樹
CreateBiTree(T->rchild);
//構造右子樹
}
return
OK;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
/************************************************************/
/* 按層次順序創建一棵二叉樹 :隊列 */
/************************************************************/
Status LevelCreateBiTree(BiTree &T)
{
BiTree p,s;
//p指向父親結點,s指向孩子結點
Queue BiNodeQueue;
char
ch;
ch=
getchar
();
if
(ch==
' '
)
{
return
NULL;
}
T=(BiTNode*)
malloc
(
sizeof
(BiTNode));
//生成根結點
T->data=ch;
EnQueue(BiNodeQueue,T);
//用隊列實現層次遍歷
while
(!BiNodeQueue.Empty())
{
DeQueue(BiNodeQueue,p);
ch=
getchar
();
//爲了簡化操做,分別對左右子結點進行賦值。
if
(ch!=
' '
)
//子樹不空則進隊列進行擴充。下同
{
s=(BiTNode*)
malloc
(
sizeof
(BiTNode));
s->data=ch;
p->lchild=s;
EnQueue(BiNodeQueue,s);
}
else
{
p->lchild=NULL;
}
ch=
getchar
();
if
(ch!=
' '
)
{
s=(BiTNode*)
malloc
(
sizeof
(BiTNode));
s->data=ch;
p->rchild=s;
EnQueue(BiNodeQueue,s);
}
else
{
p->rchild=NULL;
}
}
return
OK;
}
|
2.二叉樹的前序遍歷:指針
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/*******************************************/
/* 按照前序遞歸遍歷二叉樹 */
/*******************************************/
Status PreOrderTraverse(BiTree T)
{
if
(T)
{
printf
(
"%d"
,T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
return
OK;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/*******************************************/
/* 按照前序非遞歸遍歷二叉樹:棧 */
/*******************************************/
Status PreOrderTraverse(BiTree T)
{
stack S;
InitStack(S);
BiTree p=T;
//p指向當前訪問的結點
while
(p||!StackEmpty(S))
{
if
(p)
{
printf
(
"%c"
,p->data);
Push(S,p);
p=p->lchild;
}
else
{
Pop(S,p);
p=p->rchild;
}
}
return
OK;
}
|
3.二叉樹的中序遍歷:code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/*******************************************/
/* 按照中序遞歸遍歷二叉樹 */
/*******************************************/
Status InOrderTraverse(BiTree T)
{
if
(T)
{
InOrderTraverse(T->lchild);
printf
(
"%d"
,T->data);
InOrderTraverse(T->rchild);
}
return
OK;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/*******************************************/
/* 按照中序非遞歸遍歷二叉樹 */
/*******************************************/
Status InOrderTraverse(BiTree T)
{
stack S;
BiTree p;
InitStack(S); Push(S, T);
while
(!StackEmpty(S))
{
while
(GetTop(S, p) && p)
Push(S, p->lchild);
// 向左走到盡頭
Pop(S, p);
// 空指針退棧(葉子的左孩子)
if
(!StackEmpty(S))
{
// 訪問結點,向右一步
Pop(S, p);
printf
(
"%d"
,p->data);
//當前根結點
Push(S, p->rchild);
}
}
return
OK;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/*******************************************/
/* 按照中序非遞歸遍歷二叉樹 */
/*******************************************/
Status InOrderTraverse(BiTree T)
{
stack S;
InitStack(S);
BiTree p=T;
while
(p || !StackEmpty(S))
{
if
(p)
{
Push(S, p);
p = p->lchild;
}
// 非空指針進棧,繼續左進
else
{
// 上層指針退棧,訪問其所指結點,再向右進
Pop(S, p);
printf
(
"%d"
,p->data);
p = p->rchild;
}
}
return
OK;
}
|
4.二叉樹的後序遍歷:對象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/*******************************************/
/* 按照後序遞歸遍歷二叉樹 */
/*******************************************/
Status PostOrderTraverse(BiTree T)
{
if
(T)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf
(
"%d"
,T->data);
}
return
OK;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/*******************************************/
/* 按照後序非遞歸遍歷二叉樹 */
/*******************************************/
Status PostOrderTraverse(BiTree T)
{
stack S;
InitStack(S);
BiTree p=T,pre=NULL;
while
( p || !StackEmpty(S))
{
if
(p)
{
Push(S,p);
p = p->left;
}
else
{
Pop(S,p);
if
(p->right!=NULL && pre!=p->right)
{
//pre指向上次訪問的右結點,避免再次訪問
p=p->right;
}
else
{
printf
(
"%d"
,p->data);
pre=p;
p=NULL;
}
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
/*******************************************/
/* 按照後序非遞歸遍歷二叉樹 */
/*******************************************/
Status PostOrderTraverse(BiTree T)
{
BiTree p = T,last = NULL;
stack S;
InitStack(S);
Push(S,p);
while
(!StackEmpty(S))
{
Pop(S,p);
if
(last == p->left || last == p->right)
//左右子樹已經訪問完了,該訪問根節點了
{
printf
(
"%d"
,p->data);
last = p;
}
else
if
(p->left || p->right)
//左右子樹未訪問,當前節點入棧,左右節點入棧
{
Push(S,p);
if
(p->right)
Push(S,p->right);
if
(p->left)
Push(S,p->left);
}
else
//當前節點爲葉節點,訪問
{
printf
(
"%d"
,p->data);
last = p;
}
}
}
|
5.二叉樹的層次遍歷:blog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/*******************************************/
/* 按照層次遍歷二叉樹 */
/*******************************************/
void
LevelOrderTraverse(BiTree T)
{
Queue BiNodeQueue;
BiTree p=T;
EnQueue(BiNodeQueue,p);
while
(!BiNodeQueue.Empty())
{
DeQueue(BiNodeQueue,p);
if
(p)
{
printf
(
"%c"
,p->data);
EnQueue(BiNodeQueue,p->lchild);
EnQueue(BiNodeQueue,p->rchild);
}
}
}
|
6.交換左右子樹:遞歸
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/*******************************************/
/* 遞歸法將二叉樹的左右子樹互換 */
/*******************************************/
void
Exchange(BiTree T)
{
BiTree temp;
if
(T)
{
Exchange1(T->lchild);
Exchange1(T->rchild);
temp=T->lchild;
T->lchild=T->rchild;
T->rchild=temp;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/*******************************************/
/* 非遞歸法將二叉樹的左右子樹互換 */
/*******************************************/
void
Exchange(BiTree T)
{
stack S;
InitStack(S);
BiTree p=T,temp;
while
(p||!StackEmpty(S))
{
if
(p)
{
Push(S,p);
temp=p->lchild;
p->lchild=p->rchild;
p->rchild=temp;
p=p->lchild;
}
else
{
Pop(S,p);
p->rchild;
}
}
}
|
7.統計二叉樹中葉子結點的數目:隊列
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/*******************************************/
/* 遞歸法求葉子結點個數 */
/*******************************************/
int
LeavesNum(BiTree T)
{
if
(T)
{
if
(T->lchild==NULL&&T->rchild==NULL)
{
return
1;
}
return
LeavesNum(T->lchild)+LeavesNum(T->rchild);
}
return
0;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/*******************************************/
/* 非遞歸法求葉子結點個數 */
/*******************************************/
int
LeavesNum(BiTree T)
{
int
count=0;
stack S;
|