一、二叉树的抽象数据类型:
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.二叉树的创建:
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.二叉树的中序遍历:
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.二叉树的层次遍历:
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;
InitStack(S);
BiTree p=T;
while
(p||!StackEmpty(S))
{
if
(p)
{
Push(S,p);
if
(p->lchild==NULL&&p->rchild==NULL)
{
count++;
}
p=p->lchild;
}
else
{
Pop(S,p);
p=p->rchild;
}
}
return
count;
}
|
8.求二叉树的深度:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/**********************************************/
/* 求一棵树的高度 */
/**********************************************/
int
Depth(BiTree T)
{
int
lh = rh =0 ;
BiTree p=T;
if
(p==NULL)
{
return
0 ;
}
else
{
lh = Depth( p->lchild ) ;
rh = Depth( p->rchild ) ;
return
( lh > rh ? lh : rh ) + 1 ;
}
}
|
9.判断两棵树是否等价:
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
|
/*******************************************************/
/* 判断两棵是否等价 */
/*******************************************************/
int
Is_equal( BiTree T1 , BiTree T2 )
{
int
t=0;
if
(NULL == T1 && NULL == T2)
{
t=1;
}
else
{
if
(NULL !=T1 &&NULL != T2 )
{
if
(T1->data == T2->data)
{
if
(Is_equal(T1->lchild,T2->lchild))
{
t=Is_equal(T1->rchild,T2->rchild);
}
}
}
}
return
t;
}
|
10.查找某个信息是否在这棵树中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/****************************************************/
/* 查找某个信息是否在这棵树中 */
/****************************************************/
BiTree Locate(BiTree T,
char
x)
{
BiTree p=T;
if
(P==NULL)
return
NULL;
else
{
if
( P -> data == x )
return
P;
else
{
p = Locate(P->lchild,x);
if
(p)
return
p;
else
return
Locate(P->rchild,x);
}
}
}
|
11.结点个数:
1
2
3
4
5
6
7
8
9
10
11
|
/****************************************************/
/* 树的结点个数 */
/****************************************************/
int
Num_Of_Node(BiTree t)
{
if
(t==NULL)
return
0 ;
else
return
Num_Of_Node(t->lchild)+Num_Of_Node(t->rchild)+1;
}
|
12.