求二叉树中节点的最大距离

求二叉树中节点的最大距离
求二叉树中节点的最大距离

求二叉树中节点的最大距离
如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义“距 离”为两个节点之间边的个数。 写一个程序求一棵二叉树中相距最远的两个节点之间的距离。 如图 3-11 所示,粗箭头的边表示最长距离:
图 3-11
树中相距最远的两个节点 A,B

分析与解法
我们先画几个不同形状的二叉树,(如图 3-12 所示),看看能否得到一些启示。
图 3-12
几个例子?
从例子中可以看出,相距最远的两个节点,一定是两个叶子节点,或者是一个叶子节点 到它的根节点。(为什么?) 【解法一】 根据相距最远的两个节点一定是叶子节点这个规律,我们可以进一步讨论。 对于任意一个节点,以该节点为根,假设这个根有 K 个孩子节点,那么相距最远的两 个节点 U 和 V 之间的路径与这个根节点的关系有两种情况: 1. 若路径经过根Root,则U和V是属于不同子树的,且它们都是该子树中到根节点最远 的节点,否则跟它们的距离最远相矛盾。这种情况如图3-13所示:
图 3-13
相距最远的节点在左右最长的子树中

2. 如果路径不经过Root,那么它们一定属于根的K个子树之一。并且它们也是该子树中 相距最远的两个顶点。如图3-14中的节点A:
图 3-14
相距最远的节点在某个子树下
因此,问题就可以转化为在子树上的解,从而能够利用动态规划来解决。 设第 K 棵子树中相距最远的两个节点:Uk 和 Vk,其距离定义为 d(Uk, Vk),那么节点 Uk 或 Vk 即为子树 K 到根节点 Rk 距离最长的节点。不失一般性,我们设 Uk 为子树 K 中到根 节点 Rk 距离最长的节点,其到根节点的距离定义为 d(Uk, R)。取 d(Ui, R)(1≤i≤k)中 最大的两个值 max1 和 max2,那么经过根节点 R 的最长路径为 max1+max2+2,所以树 R 中 相距最远的两个点的距离为:max{d(U1, V1), …, d(Uk, Vk),max1+max2+2}。 采用深度优先搜索如图 3-15,只需要遍历所有的节点一次,时间复杂度为 O(|E|)= O (|V|-1),其中 V 为点的集合,E 为边的集合。
图 3-15
深度遍历示意图?
示例代码如下,我们使用二叉树来实现该算法。 代码清单 3-11
// 数据结构定义

struct NODE { NODE* pLeft; NODE* pRight; int nMaxLeft; int nMaxRight; char chValue; }; int nMaxLen = 0;
// // // // //
左孩子 右孩子 左子树中的最长距离 右子树中的最长距离 该节点的值
// 寻找树中最长的两段距离 void FindMaxLen(NODE* pRoot) { // 遍历到叶子节点,返回 if(pRoot == NULL) { return; } // 如果左子树为空,那么该节点的左边最长距离为0 if(pRoot -> pLeft == NULL) { pRoot -> nMaxLeft = 0; } // 如果右子树为空,那么该节点的右边最长距离为0 if(pRoot -> pRight == NULL) { pRoot -> nMaxRight = 0; } // 如果左子树不为空,递归寻找左子树最长距离 if(pRoot -> pLeft != NULL) { FindMaxLen(pRoot -> pLeft); } // 如果右子树不为空,递归寻找右子树最长距离 if(pRoot -> pRight != NULL) { FindMaxLen(pRoot -> pRight); } // 计算左子树最长节点距离 if(pRoot -> pLeft != NULL) { int nTempMax = 0; if(pRoot -> pLeft -> nMaxLeft > pRoot -> pLeft -> nMaxRight) { nTempMax = pRoot -> pLeft -> nMaxLeft; } else { nTempMax = pRoot -> pLeft -> nMaxRight; } pRoot -> nMaxLeft = nTempMax + 1; } // 计算右子树最长节点距离 if(pRoot -> pRight != NULL)

{ int nTempMax = 0; if(pRoot -> pRight -> nMaxLeft > pRoot -> pRight -> nMaxRight) { nTempMax = pRoot -> pRight -> nMaxLeft; } else { nTempMax = pRoot -> pRight -> nMaxRight; } pRoot -> nMaxRight = nTempMax + 1; } // 更新最长距离 if(pRoot -> nMaxLeft + pRoot -> nMaxRight > nMaxLen) { nMaxLen = pRoot -> nMaxLeft + pRoot -> nMaxRight; } }?
扩展问题
在代码中, 我们使用了递归的办法来完成问题的求解。 那么是否有非递归的算法来解决 这个问题呢?
总结
对于递归问题的分析,笔者有一些小小的体会: 1. 先弄清楚递归的顺序。在递归的实现中,往往需要假设后续的调用已经完成,在此 基础之上,才实现递归的逻辑。在该题中,我们就是假设已经把后面的长度计算出 来了,然后继续考虑后面的逻辑; 2. 分析清楚递归体的逻辑,然后写出来。比如在上面的问题中,递归体的逻辑就是如 何计算两边最长的距离; 3. 考虑清楚递归退出的边界条件。也就说,哪些地方应该写return。 注意到以上 3 点,在面对递归问题的时候,我们将总是有章可循。

二叉树前序或中序或后序遍历

数学与计算机学院计算机系实验报告 课程名称: 数据结构 年级:2010 实验成绩: 指导教师: 黄襄念 姓名: 实验教室:6A-413 实验名称:二叉树前序或中序或后序遍历 学号: 实验日期:2012/6/10 实验序号:实验3 实验时间:8:00—11:40 实验学时:4 一、实验目的 1. 熟悉的掌握树的创建,和树的前序、中序、后序遍历。 二、实验环境 1. 操作系统:Windows7 2. 开发软件:Microsoft Visual C++ 6.0 三、实验内容 ● 程序功能 本程序完成了以下功能: 1. 前序遍历 2. 中序遍历 3. 后序遍历 ● 数据结构 本程序中使用的数据结构(若有多个,逐个说明): 1. 它的优缺点 1) 可以快速的查找数据。 2) 让数据层次更加清晰。 2. 逻辑结构图 3. 存储结构图

、、、、、、、、、、、、、、、、、、、、 4.存储结构的C/C++ 语言描述 typedef struct node { DataType data; struct node *lchild; struct node *rchild; } BiTNode, *BiTree; typedef BiTree type; ●算法描述 本程序中采用的算法 1.算法名称:递归 2.算法原理或思想 是通过访问结点的左右孩子来进行循环查找的方法,拿中序遍历来说明:先从头结点开始,再去访问头结点的右孩子如果为空就访问头结点的左孩子,依次进行访问当结点的左右孩子都为空时,就访问上一级,到了最后。 3.算法特点 它能将查找进行2分,体现出了更高效快捷的特点,并且层次很清晰。 ●程序说明 1. 2. 1)前序遍历模块:将树进行从头结点开始再左孩子再右孩子。 代码:void InOrder(BiTree root) { Stack S(100); initStack(S); BiTNode *p = root; do { while(p != NULL) { Push(S, p);

二叉树习题(answer)

一、下面是有关二叉树的叙述,请判断正误() (). 若二叉树用二叉链表作存贮结构,则在n个结点的二叉树链表中只有n—1个非空指针域。 ().二叉树中每个结点的两棵子树的高度差等于1。 ().二叉树中每个结点的两棵子树是有序的。 ().二叉树中每个结点有两棵非空子树或有两棵空子树。 ()二叉树中每个结点的关键字值大于其左非空子树(若存在的话)所有结点的关键字值,且小于其右非空子树(若存在的话)所有结点的关键字值。(应当是二叉排序树的特点) ().二叉树中所有结点个数是2k-1-1,其中k是树的深度。(应2i-1) ().二叉树中所有结点,如果不存在非空左子树,则不存在非空右子树。 ().对于一棵非空二叉树,它的根结点作为第一层,则它的第i层上最多能有2i—1个结点。(应2i-1)()用二叉链表法(link-rlink)存储包含n个结点的二叉树,结点的2n个指针区域中有n+1个为空指针。 (正确。用二叉链表存储包含n个结点的二叉树,结点共有2n个链域。由于二叉树中,除根结点外,每一个结点有且仅有一个双亲,所以只有n-1个结点的链域存放指向非空子女结点的指针,还有n+1个空指针。)即有后继链接的指针仅n-1个。 (√)10.具有12个结点的完全二叉树有5个度为2的结点。 最快方法:用叶子数=[n/2]=6,再求n2=n0-1=5 二、填空() 1.由3个结点所构成的二叉树有5种形态。 2. 一棵深度为6的满二叉树有n1+n2=0+ n2= n0-1=31 个分支结点和26-1 =32个叶子。 注:满二叉树没有度为1的结点,所以分支结点数就是二度结点数。 3.一棵具有257个结点的完全二叉树,它的深度为9。 (注:用 log2(n) +1= +1=9 4.设一棵完全二叉树有700个结点,则共有350个叶子结点。 答:最快方法:用叶子数=[n/2]=350

二叉树的建立与先序中序后序遍历 求叶子节点个数 求分支节点个数 求二叉树的高度

/*一下总结一些二叉树的常见操作:包括建立二叉树先/中/后序遍历二叉树求二叉树的叶子节点个数 求二叉树的单分支节点个数计算二叉树双分支节点个数计算二叉树的高度计算二叉树的所有叶子节点数*/ #include //c语言的头文件 #include//c语言的头文件stdlib.h千万别写错了 #define Maxsize 100 /*创建二叉树的节点*/ typedef struct BTNode //结构体struct 是关键字不能省略结构体名字可以省略(为无名结构体) //成员类型可以是基本型或者构造形,最后的为结构体变量。 { char data; struct BTNode *lchild,*rchild; }*Bitree; /*使用先序建立二叉树*/ Bitree Createtree() //树的建立 { char ch; Bitree T; ch=getchar(); //输入一个二叉树数据 if(ch==' ') //' '中间有一个空格的。 T=NULL; else { T=(Bitree)malloc(sizeof(Bitree)); //生成二叉树(分配类型*)malloc(分配元素个数*sizeof(分配类型)) T->data=ch; T->lchild=Createtree(); //递归创建左子树 T->rchild=Createtree(); //地柜创建右子树 } return T;//返回根节点 } /*下面先序遍历二叉树*/

/*void preorder(Bitree T) //先序遍历 { if(T) { printf("%c-",T->data); preorder(T->lchild); preorder(T->rchild); } } */ /*下面先序遍历二叉树非递归算法设计*/ void preorder(Bitree T) //先序遍历非递归算法设计{ Bitree st[Maxsize];//定义循环队列存放节点的指针Bitree p; int top=-1; //栈置空 if(T) { top++; st[top]=T; //根节点进栈 while(top>-1) //栈不空时循环 { p=st[top]; //栈顶指针出栈 top--; printf("%c-",p->data ); if(p->rchild !=NULL) //右孩子存在进栈 { top++; st[top]=p->rchild ; } if(p->lchild !=NULL) //左孩子存在进栈 { top++; st[top]=p->lchild ; } } printf("\n"); } }

二叉树求节点数

二叉树求节点数 #include #include #include //函数状态码定义 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW -1 #define INFEASIBLE -2 #define NULL 0 typedef int Status; typedef int TElemType; typedef struct BiTNode{ TElemType data; struct BiTNode *lchild,*rchild; }BitNode, *BiTree; Status PrintTElem(TElemType e) { printf("%d ",e); return OK; } Status CreateBiTree(BiTree &T){ TElemType e; scanf("%d",&e); if(e==0 )T=NULL; else{ T=(BiTree)malloc(sizeof(BiTNode)); if(!T)exit(OVERFLOW); T->data=e; CreateBiTree(T->lchild); CreateBiTree(T->rchild);

} return OK; } Status PreOrderTraverse(BiTree T,Status(*visit)(TElemType)) { if(T){ if( (*visit)(T->data) ) if( PreOrderTraverse(T->lchild,(*visit)) ) if( PreOrderTraverse(T->rchild,(*visit)) ) return OK; return ERROR; } else return OK; } int NodeCount(BiTree T){ //递归法统计所有结点的个数 int n; if(T==NULL)n=0; else n=1+NodeCount(T->lchild)+NodeCount(T->rchild); return n; } void main() { BiTree T; CreateBiTree(T); printf("二叉树T的先序输出序列为:"); PreOrderTraverse(T,PrintTElem); printf("\n"); printf("二叉树T的叶子节点数为 %d\n",NodeCount(T)); }

数据结构第6章二叉树作业及答案教材

数据结构第6章二叉树作业及答案教材

第六章树及二叉树 一、下面是有关二叉树的叙述,请判断正误 (√)1. 若二叉树用二叉链表作存贮结构,则在n个结点的二叉树链表中只有n—1个非空指针域。 (×)2.二叉树中每个结点的两棵子树的高度差等于1。 (√)3.二叉树中每个结点的两棵子树是有序的。 (×)4.二叉树中每个结点有两棵非空子树或有两棵空子树。 (×)5.二叉树中每个结点的关键字值大于其左非空子树(若存在的话)所有结点的关键字值,且小于其右非空子树(若存在的话)所有结点的关键字值。(应当是二叉排序树的特点)(×)6.二叉树中所有结点个数是2k-1-1,其中k是树的深度。(应2i-1) (×)7.二叉树中所有结点,如果不存在非空左子树,则不存在非空右子树。 (×)8.对于一棵非空二叉树,它的根结点作为第一层,则它的第i层上最多能有2i—1个结点。(应2i-1) (√)9.用二叉链表法(link-rlink)存储包含n个结点的二叉树,结点的2n个指针区域中有n+1个为空指针。 (正确。用二叉链表存储包含n个结点的二叉树,结点共有2n个链域。由于二叉树中,除根结点外,每一个结点有且仅有一个双亲,所以只有n-1个结点的链域存放指向非空子女结点的指针,还有n+1个空指针。)即有后继链接的指针仅n-1个。 (√)10.具有12个结点的完全二叉树有5个度为2的结点。 最快方法:用叶子数=[n/2]=6,再求n 2=n -1=5 ( ) 11、哈夫曼树中没有度为1的结点,所以必为满二叉树。 ( )12、在哈夫曼树中,权值最小的结点离根结点最近。 ( )13、线索二叉树是一种逻辑结构。 (√)14、深度为K的完全二叉树至少有2K-1个结点。 (√ )15、具有n个结点的满二叉树,其叶结点的个数为(n+1)/2。 (√ )16、前序和中序遍历用线索树方式存储的二叉树,不必使用栈。 (╳ )17、哈夫曼树是带权路径长度最短的树,路径上权值较大的点离根较远。 二、填空 1.由3个结点所构成的二叉树有5种形态。 2. 一棵深度为6的满二叉树有n 1+n 2 =0+ n 2 = n -1=31 个分支结点和26-1 =32个叶子。 注:满二叉树没有度为1的结点,所以分支结点数就是二度结点数。 3.一棵具有257个结点的完全二叉树,它的深度为9。 (注:用? log 2 (n) ?+1= ? 8.xx ?+1=9 4.设一棵完全二叉树有700个结点,则共有 350个叶子结点。 答:最快方法:用叶子数=[n/2]=350 5. 设一棵完全二叉树具有1000个结点,则此完全二叉树有500个叶子结点,有499个度为2的结点,有1个结点只有非空左子树,有0个结点只有非空右子树。

求二叉树的深度叶子结点数总结点数()

#include"malloc.h" #define NULL 0 #include"stdio.h" typedef struct node { char data; struct node *lchild,*rchild; }NODE; int count; NODE *crt_bt_pre()/*二叉树先序创建算法*/ { NODE * bt; char ch; printf("\n\t\t\t"); scanf("%c",&ch); getchar(); if(ch==' ') bt=NULL; else { bt=(NODE*)malloc(sizeof(NODE)); bt->data=ch; printf("\n\t\t\t请输入%c结点的左孩子:",bt->data); bt->lchild=crt_bt_pre(); printf("\n\t\t\t请输入%c结点的右孩子:",bt->data); bt->rchild=crt_bt_pre(); } return(bt); } void Preorder(NODE* bt)/*二叉树先序递归遍历算法*/ { if(bt!=NULL) { printf("\n\t\t\t %c",bt->data); Preorder(bt->lchild); Preorder(bt->rchild); } } void Inorder(NODE* bt) {

if(bt!=NULL) { Inorder(bt->lchild); printf("\n\t\t\t %c",bt->data); Inorder(bt->rchild); } } void Postorder(NODE* bt) { if(bt!=NULL) { Postorder(bt->lchild); Postorder(bt->rchild); printf("\n\t\t\t %c",bt->data); } } int CountLeaf(NODE *bt)/*求二叉树叶子结点数的递归遍历算法*/ { if(bt==NULL) return 0; if(bt->lchild==NULL&&bt->rchild==NULL) count++; CountLeaf(bt->lchild); CountLeaf(bt->rchild); return(count); } int CountNode (NODE* bt)/*求二叉树结点数的递归遍历算法*/ { if(bt==NULL) return 0; else count++; CountNode(bt->lchild); CountNode(bt->rchild); return(count); } int TreeDepth(NODE* bt)/*求二叉树深度的递归遍历算法*/ { int x,y; if(bt==NULL)

C语言实现二叉树的前序遍历(递归)

C语言实现二叉树的前序遍历算法实现一: #include #include typedef struct BiTNode//定义结构体 { char data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; void CreateBiTree(BiTree &T) //前序创建树 { char ch; scanf("%c",&ch); if(ch==' ') T=NULL; else { T=(struct BiTNode *)malloc(sizeof(struct BiTNode)); T->data=ch; CreateBiTree(T->lchild); CreateBiTree(T->rchild); } } int print(BiTree T)//前序遍历(输出二叉树) { if(T==NULL)return 0; else if(T->lchild==NULL && T->rchild==NULL)return 1; else return print(T->lchild)+print(T->rchild); } void main()//主函数 { BiTree T; CreateBiTree(T); printf("%d\n",print(T)); } 算法实现二: #include

#include struct BiTNode//定义结构体 { char data; struct BiTNode *lchild,*rchild; }; int num=0; void CreatBiTree(struct BiTNode *&p) //前序创建树 { char ch; scanf("%c",&ch); if(ch==' ') p=NULL; else { p=(struct BiTNode *)malloc(sizeof(struct BiTNode)); p->data=ch; CreatBiTree(p->lchild); CreatBiTree(p->rchild); } } void print(struct BiTNode *p) //前序遍历(输出二叉树){ if(p!=NULL) { if(p->lchild==NULL&&p->rchild==NULL) else { print(p->lchild); print(p->rchild); } } } void main()//主函数 { struct BiTNode *p; CreatBiTree(p); print(p); printf("%d\n",num); } 供测试使用的数据

数据结构中二叉树各种题型详解及程序

树是一种比较重要的数据结构,尤其是二叉树。二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒。二叉树是递归定义的,因此,与二叉树有关的题目基本都可以用递归思想解决,当然有些题目非递归解法也应该掌握,如非递归遍历节点等等。本文努力对二叉树相关题目做一个较全的整理总结,希望对找工作的同学有所帮助。 二叉树节点定义如下: structBinaryTreeNode { intm_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; 相关链接: 轻松搞定面试中的链表题目 题目列表: 1. 求二叉树中的节点个数 2. 求二叉树的深度 3. 前序遍历,中序遍历,后序遍历 4.分层遍历二叉树(按层次从上往下,从左往右) 5. 将二叉查找树变为有序的双向链表 6. 求二叉树第K层的节点个数 7. 求二叉树中叶子节点的个数 8. 判断两棵二叉树是否结构相同 9. 判断二叉树是不是平衡二叉树 10. 求二叉树的镜像 11. 求二叉树中两个节点的最低公共祖先节点 12. 求二叉树中节点的最大距离 13. 由前序遍历序列和中序遍历序列重建二叉树 14.判断二叉树是不是完全二叉树 详细解答 1. 求二叉树中的节点个数 递归解法: (1)如果二叉树为空,节点个数为0 (2)如果二叉树不为空,二叉树节点个数= 左子树节点个数+ 右子树节点个数+ 1 参考代码如下: 1.int GetNodeNum(BinaryTreeNode * pRoot) 2.{ 3.if(pRoot == NULL) // 递归出口 4.return 0; 5.return GetNodeNum(pRoot->m_pLeft) + GetNodeNum(pRoot->m_pRight) + 1; 6.}

实现二叉树中所有节点左右子树的交换

实现二叉树中所有节点左右子树的交换 IMB standardization office【IMB 5AB- IMBK 08- IMB 2C】

数据结构课程设计 实验报告 题目名称:实现二叉树中所有节点左右子树的交换学院:信息科学与工程学院 专业班级:计算机科学与技术1003班 姓名:叶成功 学号: 指导教师:陈国良教授李立三教授 日期:2012年7月3日 目录

一、问题描述 二叉树是一种常见的特殊的树型结构,在计算机领域有着极为广泛的应用。在二叉树的一些应用中,常常要求在树中查找具有某些特征的结点或者对树中全部结点逐一进行某种处理,这就提出了遍历二叉树。根据遍历的方向的不同,有前序遍历、中序遍历、后序遍历以及层序遍历。在本次课程设计中,要求学生通过编写程序完成对二叉树的一些操作,比如可以构造二叉树、打印二叉树、遍历二叉树以及对左右子树进行交换等等。

二、基本要求 要求:。构造一颗20个节点的完全二叉树或者20个节点以上的满二叉树。 实现如下步骤: (1)实现二叉树的构造过程,并打印出二叉树 (2)对该二叉树分别用层序、前序、中序和后序四种不同的方法进行遍历; (3)将该二叉树的所有左右子树进行交换,得到新的二叉树,并打印出该二叉树; (4)对新获得的二叉树分别用层序、前序、中序和后序四种不同的方法进行遍历。 三、数据结构的设计 由数据结构中二叉树的定义可知,二叉树的结点由一个数据元素和分别指向其左、右子树的两个分支构成,所以在本程序二叉树的构造是采用二叉链表的链式存储结构,链表中的结点应包含三个域:数据域和左、右孩子的指针域。这种存储结构可以方便二叉树的建立以及遍历。 1、结点的数据结构 structnode { chardata; structnode*lchild,*rchild; } 2、基本操作 voidCreate(BiTNode**p) 初始条件:按照结点的结构体构造二叉树; 操作结果:构造一棵二叉树。 voidPreOrderTraverse(BiTreeT)

二叉树叶子结点个数计算

计算二叉树叶子结点 1.程序设计简介 已知一棵二叉树,求该二叉树中叶子结点的个数。 2.基本要求 (1)设计二叉树的二叉链表为存储结构 (2)设计求叶子结点个数的递归算法 (3)输入:一颗二叉树 (4)输出:二叉树中叶子结点的个数 3.实现提示 (1)存储设计 二叉树采用二叉链表为存储结构 (2)算法设计 求二叉树中叶子结点个数,即求二叉树的所有结点中左、右子树均为空的结点个数之和。可以将此问题转化为遍历问题,在遍历中“访问一个结点”时判断该结点是不是叶子,若是则将计数器累加。 4.源程序 #include #include using namespace std;

struct BiNode 行与测试 6.调试感想 非递归算法求叶子结点的个数 #include #include using namespace std; struct node { int data; node *lchild; node *rchild; }; node *root=NULL; void mid(node*root,int key=500) { int sum=0; stacks; while(NULL!=root || !()) { if(NULL!=root) {

(root); root=root->lchild; } else { root=(); // cout<data<<" "; if(NULL==root->lchild && NULL==root->rchild) ++sum; (); root=root->rchild; } } cout<data=100; node *a=new node; node *b=new node; node *a1=new node; node *a2=new node; node *b1=new node; node *b2=new node; a->data=200; b->data=300; a1->data=400; a2->data=500; b1->data=600; b2->data=700; root->lchild=a; root->rchild=b; a->lchild=a1; a->rchild=a2;

C++二叉树的前序,中序,后序,层序遍历的递归算法55555

#include using namespace std; #define queuesize 100 #define ERROR 0 #define OK 1 typedef struct BiTNode//二叉树 { char data; struct BiTNode *lchild,*rchild; }BinNode; typedef BinNode * BiTree;//定义二叉链表指针类型 typedef struct { int front,rear; BiTree data[queuesize];//循环队列元素类型为二叉链表结点指针 int count; }cirqueue;//循环队列结构定义 void leverorder(BiTree t) { cirqueue *q; BiTree p; q=new cirqueue;//申请循环队列空间 q->rear=q->front=q->count=0;//将循环队列初始化为空 q->data[q->rear]=t;q->count++;q->rear=(q->rear+1)%queuesize;//将根结点入队 while (q->count) //若队列不为空,做以下操作 if (q->data[q->front]) //当队首元素不为空指针,做以下操作 { p=q->data[q->front]; //取队首元素*p cout<data; q->front=(q->front+1)%queuesize;q->count--;//队首元素出队 if (q->count==queuesize)//若队列为队满,则打印队满信息,退出程序的执行cout<<"error,队列满了!"; else {//若队列不满,将*p结点的左孩子指针入队 q->count++;q->data[q->rear]=p->lchild; q->rear=(q->rear+1)%queuesize; } if (q->count==queuesize)//若队列为队满,则打印队满信息,退出程序的执行cout<<"error"; else {//若队列不满,将*p结点的右孩子指针入队 q->count++;q->data[q->rear]=p->rchild;

第6章 树和二叉树练习题及答案

一、判断题 (√)1. 若二叉树用二叉链表作存贮结构,则在n个结点的二叉树链表中只有n—1个非空指针域。 (×)2.二叉树中每个结点的两棵子树的高度差等于1。 (√)3.二叉树中每个结点的两棵子树是有序的。 (×)4.二叉树中每个结点有两棵非空子树或有两棵空子树。 (×)5.二叉树中所有结点个数是2k-1-1,其中k是树的深度。(应2i-1) (×)6.二叉树中所有结点,如果不存在非空左子树,则不存在非空右子树。 (×)7.对于一棵非空二叉树,它的根结点作为第一层,则它的第i层上最多能有2i —1个结点。(应2i-1) (√)8.用二叉链表法存储包含n个结点的二叉树,结点的2n个指针区域中有n+1个为空指针。 (√)9.具有12个结点的完全二叉树有5个度为2的结点。 ( ) 10、哈夫曼树中没有度为1的结点,所以必为满二叉树。 ( )11、在哈夫曼树中,权值最小的结点离根结点最近。 ( )12、线索二叉树是一种逻辑结构。 (√)13、深度为K的完全二叉树至少有2K-1个结点。 (√ )14、具有n个结点的满二叉树,其叶结点的个数为(n+1)/2。 (√ )15、前序和中序遍历用线索树方式存储的二叉树,不必使用栈。 (╳ )16、哈夫曼树是带权路径长度最短的树,路径上权值较大的点离根较远。 (√)17、在二叉树结点的先序序列和后序序列中,所有叶子结点的先后顺序完全相同。(√)18、二叉树的遍历操作实际上是将非线性结构线性化的过程 (√)19、树的先根遍历序列与其所转化的二叉树的先序遍历序列相同。 (╳)20、树的后根遍历序列与其所转化的二叉树的后序遍历序列相同。 二、填空 1.由3个结点所构成的二叉树有 5 种形态。 2. 线索二叉树的左线索指向其_前驱_____,右线索指向其__后继____。 3.一棵具有257个结点的完全二叉树,它的深度为 9 。 4、如某二叉树有20个叶子结点,有30个结点仅有一个孩子,则该二叉树的总结点数 为_69_____。 5. 设一棵完全二叉树具有1000个结点,则此完全二叉树有 500 个叶子结点,有 499 个度为2的结点,有 1 个结点只有非空左子树,有 0 个结点只有非空右子树。答:最快方法:用叶子数=[n/2]=500 ,n2=n0-1=499。另外,最后一结点为2i属于 左叶子,右叶子是空的,所以有1个非空左子树。完全二叉树的特点决定不可能有左空 右不空的情况,所以非空右子树数=0. 6. 一棵含有n个结点的k叉树,可能达到的最大深度为n,最小深度为 2 。

实验报告二叉树求叶子结点数目(内容清晰)

实验叶子结点的计算 姓名:xxx 班级:xxx) 学号:16130xxxxx 时间2017.10.22 1 问题描述 二叉树叶子节点的计算 1.二叉树的创建 2.二叉树的图形显示 3.二叉树叶子节点的计算 2 结构设计 二叉树叶子结点的计算主要是二叉树的创建,在这里选择的存储结构是一个链式存Data lchild rchild struct BTNode{ int data; BTNode*lchild; BTNode*rchild; }; 3 算法设计 在程序正式编写之前我定义了几个功能函数 (1)指针清空函数,预定义一个指针bt 使lchild和rchild的值分别赋予bt并且使其为空 static int clear(BTNode *bt) { if (bt) { clear(bt->lchild ); clear(bt->rchild ); cout<<"释放了指针"<

{ if(p->lchild==NULL&&p->rchild==NULL)count++; Leaf(p->lchild,count); Leaf(p->rchild,count); } return count; } (2)二叉树的创建 同样是利用递归的方式,输入参数包括指针,左右判断,以及判空条件static int create(BTNode *p,int k ,int end) { BTNode *q; int x; cin>>x; if(x!=end) { q=new BTNode; q->data =x; q->lchild=NULL; q->rchild=NULL; if(k==1)p->lchild=q; if(k==2)p->rchild=q; create(q,1,end); create(q,2,end); } return 0; }; (3)类的构造函数创建树并且输入各结点数值 在这里,采用的时先序遍历法依次输入树中的各结点数值 Step 1:定义新的结构体指针, Step 2:申请动态存储空间; Step 3:输入节点元素,并且指针后移到输入结点的后继结点,end作为结点结束标志; Step 4:重复步骤3,直到输入结束; void BinaryTree::CreateBiTree (int end) { cout<<"请按照先序序列的顺序输入二叉树,-1为空指针域标志:"<>x; if(x==end)return; p=new BTNode;

二叉树的遍历(先序、中序、后序)

实践三:树的应用 1.实验目的要求 通过本实验使学生深刻理解二叉树的性质和存储结构,熟练掌握二叉树的遍历算法。认识哈夫曼树、哈夫曼编码的作用和意义。 实验要求:建一个二叉树并按照前序、中序、后序三种方法遍历此二叉树,正确调试本程序。 能够建立一个哈夫曼树,并输出哈夫曼编码,正确调程序。写出实验报告。 2.实验主要内容 2.1 对二叉树进行先序、中序、后序递归遍历,中序非递归遍历。 2.2 根据已知的字符及其权值,建立哈夫曼树,并输出哈夫曼编码。 3.实验步骤 2.1实验步骤 ●输入p127二叉链表的定义 ●录入调试p131算法6.4,实现二叉树的构造函数 ●编写二叉树打印函数,可以通过递归算法将二叉树输出为广义表的 形式,以方便观察树的结构。 ●参考算法6.1,实现二叉树的前序、中序和后序的递归遍历算法。 为简化编程,可以将visit函数直接使用printf函数输出结点内容来 代替。 #include #include #include #define OK 1 #define ERROR 0 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 typedef char TElemType; typedef char Status; // 构造书的结构体

typedef struct BiTNode{ TElemType data; struct BiTNode *lchild, *rchild; }BiTNode, *BiTree; // 构造栈的结构体 typedef BiTree SElemType; typedef struct{ SElemType *base; SElemType *top; int stacksize; }SqStack; Status InitStack(SqStack &S){ //构造一个空栈 S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); if(!S.base)exit(-2); S.top = S.base; S.stacksize = STACK_INIT_SIZE; return OK; } Status StackEmpty(SqStack S){ //若栈S为空栈,则返回TRUE,否则返回FALSE if(S.top==S.base) return 1; else return 0; }

数据结构课程设计报告-二叉树根节点到指定节点的路径

数据结构课程设计报告-二叉树根节点到指定节点的路径 数据结构课程设计报告二叉树根节点到指定节点的路径——递归调用思想班级:__ 软件092________ 姓名:_ __________ 指导教师:__ 成绩:___________________ 信息工程学院2011 年 6 月17 日- 2 - 摘要(题目): 二叉树根节点到指定节点的路径 1.引言二叉树是n 个结点 的有穷个集合,它或者是空集(n=0),或者同时满足以下两个条件;(1)有且仅有一个称为根的结点;(2)其余结点分为两个互不相交的集合T1,T2,并且T1,T2,都是二叉树,分别称为根的左子树和右子树。二叉树形结构在客观世界中大量存在,如行政组织机构和人类社会的家谱关系等都可用二叉树结构形象地表示。在计算机应用领域,二叉树也被广泛地应用。例如在编译程序中,可用二叉树来表示源程序的语法结构;在数据库系统中,可用二叉树来表示组织信息;在计算机图形学中,可用二叉树来表示图像关系等。因此对二叉树的研究具有重要意义。2.需求分析利用一个简单的菜单,通过菜单项进行选择,实现和完成如下功能:用先序输入,建立二叉树存储结构、求指定结点的路径。对于建立二叉树存储结构,考虑到栈和队列的存储结构比较繁琐,从而定义一指针数组来一一存储该二叉树先序遍历过的结点,并对该结点进行判断是否为指定的目标结点,并进行输出等操作。 3.概要设计对二叉树采用链式存储结构,其结构定义如下:typedef struct

node{ DataType data; struct node *lchild,*rchild; }BinTNode,*BinTree; 每个结点中设置三个域,即值域data,左指针域*lchild 和右指针域*rchild。本程序分为6 大模块:全局变量定义、创建结构体、创建二叉链表存储表示、查找目标结点、求结点路径、主函数。(1)全局变量定义(2)创建结构体(3)创建二叉链表存储表示:定义二叉树的链式存储结构,输入数据生成二叉树。(4)查找目标结点:采用二叉链表作为存储结构,利用递归方法,对各个结点进行判断改结点是否在二叉树中。- 3 - (5)求结点路径:采用二叉链表作为存储结构,利用先序遍历二叉树方法以及指针数组的存储结构方法,对结点路径的遍历查找及输出。(6)主函数程序流程图重要函数有主函数int main()输入函数scanf()输出函数printf()二叉树的先序建立函数CreateBiTree()结点查找函数FindBT()求结点路径函数NodePath()4.详细设计(1)定义二叉树用链式存储结构存储二叉树。其中,了lchild 和rchild 是分别指向该结点左孩子和右孩子的指针,data 是数据元素的内容。定义二叉树结点值的类型为字符型且结点个数不超过100 个,具体实现方法如下:二叉树的根节点到指定节点的路径主程序代码输入函数输出函数 建立函数查找函数求路径函数- 4 - typedef struct node{ DataType data; struct node

第5章+树与二叉树习题解析(答)

习题五树与二叉树 一、选择题 1、一棵非空的二叉树的先序遍历序列与后序遍历序列正好相反,则该二叉树一定满足。 A、所有的结点均无左孩子 B、所有的结点均无右孩子 C、只有一个叶子结点 D、是任意一棵二叉树 2、一棵完全二叉树上有1001个结点,其中叶子结点的个数是。 A、250 B、500 C、254 D、505 E、以上答案都不对 3、以下说法正确的是。 A、若一个树叶是某二叉树前序遍历序列中的最后一个结点,则它必是该子树后序遍历序列中的最后一个结点 B、若一个树叶是某二叉树前序遍历序列中的最后一个结点,则它必是该子树中序遍历序列中的最后一个结点 C、在二叉树中,具有两个子女的父结点,在中序遍历序列中,它的后继结点最多只能有一个子女结点 D、在二叉树中,具有一个子女的父结点,在中序遍历序列中,它没有后继子女结点 4、以下说法错误的是。 A、哈夫曼树是带权路径长度最短得数,路径上权值较大的结点离根较近 B、若一个二叉树的树叶是某子树中序遍历序列中的第一个结点,则它必是该子树后序 遍历序列中的第一个结点 C、已知二叉树的前序遍历和后序遍历并不能唯一地确定这棵树,因为不知道树的根结 点是哪一个 D、在前序遍历二叉树的序列中,任何结点其子树的所有结点都是直接跟在该结点之后

的 5、一棵有124个叶结点的完全二叉树,最多有个结点。 A、247 B、248 C、249 D、250 E、251 6、任何一棵二叉树的叶结点在前(先)序、中序和后序遍历序列中的相对次序。 A、不发生变化 B、发生变化 C、不能确定 7、设a、b为一棵二叉树上的两个结点。在中序遍历时,a在b前面的条件是。 A、a在b的右方 B、a在b的左方 C、a是b的祖先 D、a是b的子孙 8、设深度为k的二叉树上只有度为0和度为2的结点,则这类二叉树上所含的结点总数为。 A、不确定 B、2k C、2k-1 D、2k+1 9、设有13个值,用它们组成一棵哈夫曼树,则该哈夫曼树共有个结点。 A、13 B、12 C、26 D、25 10、下面几个符号串编码集合中,不是前缀编码的是。 A、{0,10,110,1111} B、{11,10,001,101,0001} C、{00,010,0110,1000} D、{b,c,aa,ac,aba,abb,abc} 11、欲实现任意二叉树的后序遍历的非递归算法而不使用栈结构,最佳的方案是二叉树采用存储结构。 A、三叉链表 B、广义表 C、二叉链表 D、顺序表 12、以下说法错误的是。 A、存在这样的二叉树,对它采用任何次序遍历其结点访问序列均相同 B、二叉树是树的特殊情形 C、由树转换成二叉树,其根结点的右子树总是空的 D、在二叉树只有一棵子树的情况下也要明确指出该子树是左子树还是右子树

完全二叉树操作演示

安徽省巢湖学院计算机与信息工程学院 课程设计报告 课程名称《数据结构》 课题名称完全二叉树操作演示 专业班级计算机科学与技术专升本1班 学号 14011016、14011040、14011019 姓名李鹏王帅李泳波 联系方式 指导教师严小燕 完成日期: 2014年 12月 27 日

目录 1 数据结构课程设计任务书 (1) 1.1题目 (1) 1.2目的 (1) 1.3要求 (1) 2 总体设计 (1) 2.1功能模块设计 (1) 2.2所有功能模块流程图 (1) 3 详细设计 (2) 3.1程序中所采用的数据结构及存储结构的说明 (2) 3.2算法设计思想 (3) 3.3主要的功能函数 (3) 4 调试与测试 (3) 4.1调试方法与步骤 (4) 4.2测试结果分析与讨论 (4) 4.3测试过程中遇到的主要问题及采取的解决措施 (5) 5 时间复杂度分析 (6) 6 程序清单 (6) 7 总结 (12) 参考文献 (13)

1 数据结构课程设计任务书 1.1题目 完全二叉树操作演示 1.2目的 (1)掌握二叉树的概念和性质。 (2)掌握完全二叉树存储结构。 (3)掌握完全二叉树的基本操作。 1.3 要求 (1)创建完全二叉树(用字母表示节点)(用顺序方式存储)。 (2)求二叉树的深度和叶子结点数。 (3)实现二叉树的前序、中序、后序和层次遍历。 (4)查找给定结点的双亲、祖先和左右孩子节点。 2 总体设计 2.1 功能模块设计 根据课程设计题目的功能要求,各个功能模块的组成框图如图1: 图 1 功能组成框图 2.2 所有功能模块流程图 设计好功能模块后,各个模块的关系如下图2:

遍历二叉树老师的程序(绝对正确,实现先序、中序、后序遍历)

#include #include"stdlib.h" //节点结构体 typedef struct BiTNode { char data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; //***********先序建立二叉树中的节点****************** void CreatBiTree(BiTree *T) //指针的指针 { char ch; if((ch=getchar())==' ') *T=NULL; else { (*T)=(BiTNode *)malloc(sizeof(BiTNode)); if(!(*T)) exit(1); (*T)->data=ch; CreatBiTree(&((*T)->lchild)); CreatBiTree(&((*T)->rchild)); } } //***************先序遍历二叉树********************** void PreTravel(BiTree T) { if(T) { printf("%c",T->data); PreTravel(T->lchild); PreTravel(T->rchild); } } //*************中序遍历****************** void InOrderTravel(BiTree T) { if(T) { InOrderTravel(T->lchild); printf("%c",T->data); InOrderTravel(T->rchild); }

相关文档
最新文档