遍历算法应用

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

6.3.3 遍历算法应用

二叉树的遍历运算是一个重要的基础,对访问根结点操作的理解可包括各种各样的操作。从如下的应用实例中一是重点理解访问根结点操作的含义,二是注意对具体的实现问题是否需要考虑遍历的次序问题。

1.输出二叉树中的结点

遍历算法将走遍二叉树中的每一个结点,故输出二叉树中的结点并无次序要求,因此可用三种遍历中的任何一种算法完成,下面写出前序遍历顺序的实现算法。

void PreOrder(BiTree root)

/* 先序遍历输出二叉树结点, root为指向二叉树根结点的指针*/

{ if (root!=NULL)

{

printf (root ->data); /* 输出根结点*/

PreOrder(root ->LChild); /* 先序遍历左子树*/

PreOrder(root ->RChild); /* 先序遍历右子树*/ }

}

算法6.6 先序遍历输出二叉树中结点

思考:若要求统计二叉树中结点个数应如何去实现?

2.输出二叉树中的叶子结点

输出二叉树中的叶子结点要求与输出二叉树中的结点相比,是一个有条件的输出问题,条件是在遍历过程中走到每一个结点时须进行测试,看是否满足叶结点的条件。故只需改变算法 6.6 的黑体部分。

void PreOrder(BiTree root)

/* 先序遍历输出二叉树中叶子结点, root为指向二叉树根结点的指针*/

{ if (root!=NULL)

{

if (root ->LChild==NULL &&root ->RChild==NULL) printf (root ->data); /* 输出叶子结点*/

PreOrder(root ->LChild); /* 先序遍历左子树*/

PreOrder(root ->RChild); /* 先序遍历右子树*/

}

}

算法 6.7 先序遍历输出二叉树中叶结点

3.统计叶子结点数目

下面给出两种方法均可统计出二叉树叶子结点数目

/* LeafCount保存叶子结点的数目的全局变量,调用之前初始化值为0 */

void leaf(BiTree root)

{

if(root!=NULL)

{

leaf(root->LChild);

leaf(root->RChild);

if (root ->LChild==NULL && root

->RChild==NULL)

LeafCount++;

}

}

算法 6.8(a) 后序遍历统计叶子结点数目

/* 采用递归算法,如果是空树,返回0;如果只有一个结点,返回1;否则为左右子树的叶子结点数之和*/

int leaf(BiTree root)

{

int LeafCount;

if(root==NULL)

LeafCount =0;

else if((root->lchild==NULL)&&(root->rchild==NULL)) LeafCount =1;

else

LeafCount =leaf(root->lchild)+leaf(root->rchild);

/* 叶子数为左右子树的叶子数目之和*/ return LeafCount;

}

算法 6.8(b) 后序遍历统计叶子结点数目

思考:可否按中序统计二叉树中叶子结点个数?

4.建立二叉链表方式存储的二叉树

给定一棵二叉树,我们可以得到它的遍历序列;反过来,给定一棵二叉树的遍历序列,我们也可以创建相应的二叉链表。这里所说的遍历序列,是一种“扩展的遍历序列”。在通常的遍历序列中,均忽略空子树,而在扩展的遍历序列中,必须用特定的元素表示空子树。例如,图6.8 中二叉树的“扩展先序遍历序列”为:AB.DF..G..C.E.H..

其中用小圆点表示空子树。

利用“扩展先序遍历序列”创建二叉链表的算法:

void CreateBiTree(BiTree *bt)

{ char ch;

ch=getchar();

if(ch=='.') *bt=NULL;

else

{

*bt=(BiTree)malloc(sizeof(BiTNode));

(*bt)->data=ch;

CreateBiTree(&((*bt)->LChild));

CreateBiTree(&((*bt)->RChild));

}

}

算法6.9 用“扩展先序遍历序列”创建二叉链表5.求二叉树的高度

设函数表示二叉树bt的高度,则递归定义如下:

若bt为空,则高度为0

若bt非空,其高度应为其左右子树高度的最大值加1 二叉树的高度(深度)为二叉树中结点层次的最大值。即结点的层次自根结点起递推。设根结点为第1层的结点,所有h层的结点的左右孩子结点在h+1层。则可以通过先序遍历计算二叉树中的每个结点的层次,其中最大值即为二叉树的高度。给出后序遍历求二叉树的高度递归算法:

图6.12 二叉树高度示意图

int PostTreeDepth(BiTree bt) /* 后序遍历求二叉树的高度递归算法*/

{

int hl,hr,max;

if(bt!=NULL)

{

hl=PostTreeDepth(bt->LChild); /* 求左子树的深度*/ hr=PostTreeDepth(bt->RChild); /* 求右子树的深度*/ max=hl>hr?hl:hr; /* 得到左、右子树深度较大者*/

return(max+1); /* 返回树的深度*/

}

else return(0); /* 如果是空树,则返回0 */

}

算法6.10 后序遍历求二叉树的高度递归算法

思考:求二叉树的深度是否可用前序遍历的方式实现?若能,请写出实现算法,若不能,请说明原因。

6.按树状打印的二叉树

例:假设以二叉链表存储的二叉树中,每个结点所含数据元素均为单字母。要求实现如下图6.13。

图6.13树状打印的二叉树示意

这实际是一个二叉树的横向显示问题:因为二叉树的横向显示应是二叉树竖向显示的90。旋转,又由于二叉树的横向显示算法一定是中序遍历算法,所以把横向显示的二叉树算法改为先右子树再根结点再左子树的RDL结构,实现算法见6.11。

void PrintTree(TreeNode Boot,int nLayer) /* 按竖向树状打印的二叉树*/

{

if(Boot= =NULL) return;

PrintTree(Boot->pRight,nLayer+1);

for(int i=0;i

printf(“”);

printf(“%c\n”,Boot->ch);

相关文档
最新文档