计算机专业基础综合数据结构(树和二叉树)历年真题试卷汇编13

计算机专业基础综合数据结构(树和二叉树)历年真题试卷汇编13
计算机专业基础综合数据结构(树和二叉树)历年真题试卷汇编13

计算机专业基础综合数据结构(树和二叉树)历年真题试卷汇编

13

(总分:66.00,做题时间:90分钟)

一、综合题(总题数:4,分数:12.00)

1.已知下列字符A、B、C、D、E、F、G的权值分别为3、12、7、4、2、8,11,试填写出其对应哈夫曼树HT的存储结构的初态和终态。【北京工业大学1998五(10分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:()

解析:

设T是一棵二叉树,除叶子结点外,其他结点的度数皆为2,若T中有6个叶结点,试问:(分数:6.00)(1).T树的最大可能深度Kmax=?最小可能深度Kmin=?(分数:2.00)

__________________________________________________________________________________________ 正确答案:(正确答案:(1)T树的最大深度:Kmax=6(除根外,每层均是两个结点)。T树的最小深度Kmin=4(具有6个叶子的完全二叉树是其中的一种形态)。)

解析:

(2).T树中共有多少非叶结点?(分数:2.00)

__________________________________________________________________________________________ 正确答案:(正确答案:非叶子结点数是5(n2=n0—1)。)

解析:

(3).若叶结点的权值分别为1,2,3,4,5,6。请构造一棵哈曼夫树,并计算该哈曼夫树的带权路径长度wp1。【北京邮电大学1992一、3(15/3分)】(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:哈夫曼树见右图,其带权路径长度wp1=51从本题到97题都是哈夫曼树的试题。学生在构造哈夫曼树时常犯的错误是,在选出当前两个最小权值的结点构造二叉树后,没有把刚构造出来的二叉树的根结点加入待构造的结点中,造成最终的“哈夫曼树”是向一个方向倾斜的。值得指出的是,多数教材对哈夫曼编码规则是:哈夫曼树的左分支为0,右分支为1,个别教材规定左分支为1,右分支为0。限于篇幅,不再给出答案。)

解析:

2.已知4个字符A,E C,D的哈夫曼编码分别是1,01,000,001。下列01串是由以上4个字母构成的一段文本的哈夫曼编码:1001000011011010011010011请将上述01串还原为编码前的文本。以字符在文本中出现的次数为权值,求出这棵树的带权路径长度。【电子科技大学2013三、1(5分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(A出现5次,B出现4次,C出现1次,D出现3次带权路径长度

WPL=(1+3)*3+4*2+5*1=25。)

解析:

3.什么是前缀编码?举例说明如何利用二叉树来设计二进制的前缀编码。【中山大学1999三、1(3分)】(分数:2.00)

__________________________________________________________________________________________ 正确答案:(正确答案:前缀码是一编码不是任何其他编码前缀的编码。例如,0和01就不是前缀码,因为编码0是编码01的前缀。顺便说明,仅从编码来看,0和01是前缀码,但因历史的原因,它不被称为

前缀码,而是把一编码不是另一编码前缀的编码称为前缀码。利用二叉树可以构造前缀码,例如,以A,B,C,D为叶子可构成二叉树,将左分支解释为0,右分支解释成1,从根结点到叶子结点的0、1串就是叶子的前缀码。用哈夫曼树可构造出最优二叉树,使编码长度最短,称为哈夫曼编码。)

解析:

二、设计题(总题数:25,分数:54.00)

二叉树的带权路径长度(WPL)是二叉树中所有叶结点的带权路径长度之和。给定一棵二叉树T,采用二叉链

,其中叶结点的weight域保存该结点的非负权值。设root为指向T的根结点的指针,请设计求T的WPL的算法,要求:(分数:6.00)

(1).给出算法的基本设计思想;(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:设二叉树根结点的层次为1,在遍历二叉树的函数中增加层次参数,初始值为1。遍历二叉树,在访问结点时若是叶子结点,则求其带权路径长度,将所有叶子结点的带权路径长度相加,即得到二叉树的带权路径长度。 ()

解析:

(2).使用C或C++语言,给出二叉树结点的数据类型定义;(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:ypedef struct node {int weight;//结点的权值,设为整型struct node*left,*right;//指向结点左、右子女的指针 }BiNode,*BiTree;)

解析:

(3).根据设计思想,采用C或C++语言描述算法,关键之处给出注释。【2014年全国试题41(13分)】(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:int WPL:0;//带权路径长度初值为0,是全局变量void inorder(BiTree bt,level Iv) //bt是二叉树,1v是结点的层次,初值为1,本算法求二叉树bt的带权路径长度 (if(bt) finorder(bt一>left,iv+1);//中序遍历左子树 if(bt一>left==null&&bt一>right==null) //判断该结点是否为叶子 WPL+=(iv一1)*bt一>weight;//累加结点带权路径长度 inorder(bt一>right,Iv+1);//中序遍历右子树 } })

解析:

4.假设一个仅包含二元运算符的算术表达式以链表形式存储在二叉树BT中,写出计算该算术表达式值的算法。【东北大学2000三、2(10分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:以后序遍历方式遍历算术表达式的二叉树可以得到后缀表达式,后缀表达式求值已在前面讲过。这里给出另一种算法。重新定义二叉树结点结构为(1eft,data,val,fight),其中left和fight是左右子女的指针,data是算法表达式中的字符,val是子表达式的值。采用后序遍历,先分别求出左子树和右子树表示的子表达式的值,最后计算出表达式的最后结果。算法如下:int PostEval(BiTree bt) //以后序遍历算法求以二叉树表示的算术表达式的值 {BiTree p=bt;int Iv,rv; if(p)

(1v=PostEval(p一>lef));//求左子树表示的子表达式的值 rv=PostEval(p一>right);//求右子树表示的子表达式的值 if(!P一>left&&!P一>right) //叶子结点将数据值存到val域中 P一>val:P 一>data一‘0’;//数字字符转成整数存储else switch(p一>data) //求子表达式的值{case‘+’:P一>val=p一>left一>val+p一>right一>val;break;case ‘一’:p一>Val=p一>left一>val—P一>right 一>val;break;case ‘*’:p->val=p->left一>vai。P一>right一>val;break;case ‘/’:p一>Val=p 一>1ef七一>val/p一>right一>val; }return(p->val); } } 本算法中数值是以字符表示的,因此是一位数的算术运算。若是多位数(包括实数),要做如下修改:在建立二叉树时进行拼数,一个数输入完毕再存入二叉树结点中;本算法中的p一>val=p一>data一0,要改为p一>Val=p一>data;lv和rv的类型做相应改变。拼数算法的核心语句段如下:case 0<=x=0&&X<=‘9’)lI X==.) //拼数if(x!=‘.’) //处理整数 { num=num*10+(ord(x)-ord(‘0’));cin>>x;} //num初始值为0.0 else //处理小数

部分 {scale=10.0;cin>>x;while(x>=’0‘&&x<=。9’) {num=num+(ord(x)-ord(。0’)/scale;scale=scale*10;cin>>x; } })

解析:

5.给出算法将二叉树表示的表达式二叉树按中缀表达式输出,并加上相应的括号。【北京邮电大学2001五、3(10分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:这是用二叉树表示符号算术表达式的逆问题,即将二叉树表示的表达式还原成原表达式。二叉树的中序遍历序列与原算术表达式基本相同,差别仅在于二叉树表示中消除了括号。将中序序列加上括号就恢复原貌。当根结点运算符优先级高于左子树(或右子树)根结点运算符时,就需要加括号。核心语句段如下:if(bt) (if(bt一>ichild!=null) fbracket:Precede(bt一>data,bt一>ichild一>data) //双亲与左子女运算符优先级 if(bracket==1)printf((); InorderExp(bt一>ichild);//输出左子女表示的算术表达式if(bracket==1)printf(‘)’);//加上右括号 } printf(bt一>data);//输出根结点 if(bt一>rchild!=null) //输出右子树表示的算术表达式 {bracket=Precede(bt->data,bt一>rchild->data) if(bracket==1)printf(“C);//右子女级别低,加括号InorderExp(bt->rchi id);if(bracket==1)printf(“)”); } })

解析:

6.设计一算法分别求出二元树的叶结点,度数为l的结点,度数为2的结点的个数。【哈尔滨工业大学2002八(8分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:结点计数可以在遍历中解决。根据“访问根结点”、“递归调用左子树”、“递归调用右子树”三者位置的不同,而有前序、后序和中序遍历。叶子结点是左右子女均无的结点,度为1的结点是只有一个子女的结点,度为2的结点是左右子女均有的结点。)

解析:

7.已知深度为h的二叉树,以一维数组BT[0..2 h-2]作为其存储结构,试编写一算法,求该二叉树中叶子结点的个数,为简单起见,设二叉树中元素结点为非负整数,要求写出算法基本思想及相应的算法。【中南大学2003八(10分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:按完全二叉树形式顺序存储二叉树时,无元素的位置要当作“虚结点”。根据本题“二叉树中元素结点为非负整数”,可以设虚结点为负数。设结点序号为i(根结点编号为0),则当ih-1)/2(最后一个分支结点)时,若其2f+1和2i+2位置为虚结点,则i为叶子结点;当i≥(2 h -1)/2时,若i位置不是虚结点,则必为叶子结点。核心语句段如下: for(i=0;i k一1 if(i0)num++;//存储在数组后一半的元素是叶子结点)

解析:

8.假定用两个一维数组L[N]和R[N]作为有N个结点1,2,…,N的二元树的存储结构。L[i]和R[i]分别指示结点i的左儿子和右儿子;L[i]=O(R[i]=0)表示i的左(右)儿子为空。试写一个算法,由L和R建立一个一维数组T[b],使T[i]存放结点i的父亲;然后再写一个判别结点U是否为结点V的后代的算法。【哈尔滨工业大学1999七(14分)】【华南师范大学2000六(17分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:由指示结点i左儿子和右儿子的两个一维数组L[i]和R[i],建立指示结点i的双亲的一维数组T[i],根据T数组,判断结点U是否是结点V后代的算法,转为判断结点V是否是结点U的祖先的问题。核心语句段如下: for(i=i ; i<=N; i++)T[i]=0;//T数组初始化 for(i=1;i<=N;i++) if(L[i]!=0)T[L[i\]\]=i ;//结点i的左子女是L,则结点L的双亲是结点i for(i=1,i<=N;i++) if(R Ci]!=0)T[R[i\]\]=i ;//i的右子女是r,则r的双亲是i int parent=U;//判断U是否是v的后代while(parent!=V&&parent!=0)parent=T[parent];if(parent==V){cout<<“结点U是结点v的后代“<<<“结点u不是结点V的后代”<

解析:

9.要求二叉树按二叉链表形式存储。(1)写一个建立二叉树的算法。(2)写一个判别给定的二叉树是否是完全二叉树的算法。完全二叉树定义为:深度为K,具有N个结点的二叉树的每个结点都与深度为K的满二叉树中编号从1至Ⅳ的结点一一对应。此题以此定义为准。【西北大学2000六(12分)】【哈尔滨工业大学2000十一(14分)】【南开大学1997四 (16分)】【北京邮电大学1994九(20分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:二叉树是递归定义的,以递归方式建立最简单。核心语句段如下:cin>>x;//本题假定结点数据域为整型 if(x==0)bt=null;//空指针 else if(x>0) {bt=new(BiNode);//申请空间bt->data=x;bt->ichild=creat();bt->rchiId=creat();} else error(“输入错误”);return(bt);判定是否是完全二叉树,可以使用队列,在遍历中利用完全二又树“若某结点无左子女就不应有右子女”的原则进行判断。判断时易犯的错误是由左子树和右子树都是完全二叉树,推出整棵二叉树必是完全二叉树的错误结论。核心语句段如下:if(p==null)return(1);//p是二叉树QueueInit(Q);QueueIn(Q,p);//初始化队列,根结点指针入队 while(!QueueEmpty(Q)) (p=Queueout(Q);//出队

if(p->ichild&&!tag)QueueIn(Q,p->ichild);//左子女入队 else if(p一>ichild)return 0;//前边已有结点为空,本结点不空else tag=l;//首次出现结点为空if(p一>rchild&&!tag)QueueIn(Q,P一>rchild);//右子女入队 else if(p->rchiid)return 0;else tag=1 ; }//while)

解析:

10.有n个结点的完全二叉树存放在一维数组A[1..n]中,试据此建立一棵用二叉链表表示的二叉树,根由tree指向。【南京理工大学1998七、1(6分)】【同济大学2005三、2(7分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:BiTree Creat(EiemType A[],int i)//初始调用时,i=i {BiTree tree;

if(i<=n){tree=new(BiNode);tree一>data=A[i]; if(2*i>n)tree->ichild=null ; ease

tree->Ichild=Creat(A,2*i);if(2*i+1>n)tree->rchild=null ;e18e tree->rchild=Creat(A,2*i+1);} return(tree); })

解析:

11.设计算法将一棵以二叉链表存储的二叉树按顺序方式存储到一维数组中。(注:按层从上到下,由左到右)。【中科院研究生院2005四(15分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:将以二叉链表存储的二叉树转为顺序存储结构,要按完全二叉树形式顺序存储,无元素的位置要当作“虚结点”。一维数组A空间要足够大,开始将一维数组元素都初始化为虚结点。然后将二叉树的结点存入A的适当位置上。核心语句段如下: if(bt) fA[i]=bt一>data;//初始调用时,i=1 if(bt一>ichild)Creat(A,2*i,bt->Ichiid);if(bt->rchild)Creat(A,2*i+1,bt->rchild);}) 解析:

12.已知深度为h的二叉树采用顺序存储结构已存放于数组BT[1:2 h一1】中,请写一非递归算法,产生该二叉树的二叉链表结构。设二叉链表中链结点的构造为(1child,data,rchild),根结点所在链结点的指针由T给出。【北京师范大学2005六、3(15分)】【北京航空航天大学1999七(15分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:设栈S,元素结构是(int hum,BiTree bt),初始调用num=1;设n=2 n-1。top=1;S[1]={1,bt}; while(i<=n&&top>0) {j=s[top].num;t=S[top一一].bt;if(BT[j]!=‘#’11#是虚结点{t=new(BiNode);t->data=BT[j];if(BT[j*2+1]!=‘#’) S[++top]={j*2+1,bt一>rchild);i=2*j;} }) 解析:

13.二叉树的动态二叉链表结构中的每个结点有三个字段:dam,lchild,rchild。其中指针lchild和rchild 的类型为bike。静态二叉链表是用数组作为存储空间,每个数组元素存储二叉树的一个结点,也有三个字段:data,lchild,rchild。所不同的是,lchild和rdhild为integer型,分别用于存储左右孩子的下

标,如果没有左右孩子,则相应的值为0。例如,下面左图所示的二又树的静态二叉链表如右图所示。

编写算法由二叉树的动态二叉链表构造出相应的静态二又链表a[1..n],并写出其调用形式和有关的类型描述。其中n为一个确定的整数。【合肥工业大学2000五、3(8分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:静态链表中结点是按动态二叉链表的前序遍历顺序存放的。首先对动态二叉链表的二叉树进行前序遍历,填写静态链表的“下标”和data域,再对动态二叉链表的二叉树进行层次遍历,设队列Q,填写静态链表的lchild域和rchild域。)

解析:

14.假设以双亲表示法作树的存储结构,写出双亲表示的类型说明,并编写求给定的树的深度的算法。(注:已知树中结点数)【清华大学1994七(15分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:以双亲表示法作树的存储结构,对每一结点,找其双亲,双亲的双亲,直至(根)

结点,就可求出每一结点的层次,取其结点的最大层次就是树的深度。核心语句段如下:int maxdepth=0;for(i=1;io){temp++; t=t.nodes[f].parent ;} //深度加1,并取新的双亲 if(temp>maxdepth) maxdepth=temp;//最大深度更新 } return(maxdepth);//返回树的深度)

解析:

15.设一棵二叉树用二叉链表表示,求该树的高度。【南京航空航天大学2004二、2(12分)】【北京理工大学2000四3(4)】【北京轻工业学院1997一(15分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:二叉树是递归定义的,其运算最好采取递归方式。 int Height(btre bt) //求二叉树bt的深度 fint hl,hr;//hl和hr分别是左子树和右子树的深度 if(bt==null)return(0);else(hl=Height(bt一>ich);hr=Height(bt一>rch);if(h1>hr)return(hl+1);else return(hr+1);} }) 解析:

16.二叉树以链接形式(1eft,data,right)存储,给出求二叉树宽度的算法,所谓宽度是二又树的各层上,具有结点数最多的那一层上的结点总数。【吉林大学2006四(10分)】【华南理工大学2004三、1(10分)】(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:求最大宽度可采用层次遍历的方法,记下各层结点数,取其最大宽度。Q[rear]=bt;//根结点入队列 while(front<=last) //front,rear初值为1,last同层最右结点在队列中的位置(p=Q[front++];temp++;//同层元素数加1,temp记当前层宽度if(p一>ichild!=null) Q[++rear]=p 一>Ichild;//左子女入队 if(p一>rchild!=null) Q[++rear]=p一>rchild;//右子女入队

if(front>last) //一层结束 {last=rear;//last指向下层最右元素 if(temp>maxw)maxw=temp;//更新当前最大宽度,maxw记最大宽度 temp=0;//准备下层 }//if }while)

解析:

17.以孩子兄弟链表为存储结构,请设计递归和非递归算法求树的深度。【北方交通大学1999五(18分)】【南京航空航天大学2000九】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:由孩子兄弟链表表示的树高度的递归模型是:若树为空,高度为零;若第一子女为空,高度为1和兄弟子树高度的大者;否则,高度为第一子女树高度加1和兄弟子树高度的大者。其非递归算法使用队列,逐层遍历树,取得树的高度。递归算法的核心语句段如下:if(bt==null)return(0);else if(1bt->firstchild)return(max(1,height(bt->nextsibling)));else(hc=height(bt一>firstchild);//第一子女树高 hs=height(bt一>nextsibling);//兄弟树高 if(hc+l>hs)return(hc+1); else return(hs); }//else 非递归遍历求以孩子兄弟链表表示的树的深度的核心语句段如下: Q[rear]=t;

//Q是以树中结点为元素的队列 while(front<=last) //初始front=rear=1 {t=Q[front++];//队头出列 while(t|=null) //层次遍历 fif(t一>firstchild)Q[++rear]=t一>firstchild;//第一子

女入队 t=t一>nextsibling;//同层兄弟指针后移 } if(front>last) //本层结束,深度加1(初始深度为0) {h++;last=rear;} //last再移到指向当前层最右一个结点 })

解析:

18.设一棵二叉树的结点结构为(LLINK,INFO,RLINK),ROOT为指向该二叉树根结点的指针,p和g分别为指向该二叉树中任意两个结点的指针,试编写一算法ANCESTOR(RDOT,p,q,r),该算法找到p和q的最

近共同祖先结点r。【吉林大学2000二、3(12分)】【中山大学1994六(15分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:本题到22题是在以二叉链表存储的二叉树上找某结点的所有祖先,某两个结点的

最近公共祖先,从根结点到某结点的路径,根结点到每个叶子结点以及最远叶子的路径等。均应采取后序

非递归遍历。因为后序遍历最后访问根结点,当访问到某结点时,栈中所有元素均为该结点的祖先。这里

只对16题进行分析。找p和q的最近共同祖先结点r,不失一般性,设P在q的左边。后序遍历必然先遍历到结点P,栈中元素均为P的祖先。将栈复制到另一辅助栈中。再继续遍历到结点q时,将栈中元素从

栈顶开始逐个到辅助栈中去匹配,第一个匹配(即相等)的元素就是结点p和q的最近公共祖先。其核心语

句段如下: while(bt!=null || top>0) {while(bt!=null&&bt!=p&&bt!=q) //结点入栈

{S[++top].t=bt ; s[top].tag=0;bt=bt一>ichild;} //沿左分支向下 if(bt==p)//假定P在q

的左侧,遇结点P时,栈中元素均为P的祖先结点 for(i=1;i<=top; i++)sl[i]=S[i];topl=top;//栈S元素转入辅助栈s1 if(bt==q) //找到q结点 for(i:top; i>0 ; i一) //将栈中元素到sl 去匹配 {pp=s[i].t; for(j=topl;j>0;j—-) if(sl[j].t==pp){cout

遍历 }//结束while(bt!=null|| top>0) return(null);//q、p无公共祖先)

解析:

19.当一棵有n(0<=100)个结点的二叉树按顺序存储方式存储在bf[1..n]中时,试写一个算法,求出二叉树中结点值分别为x和y的两个结点的最近的公共祖先结点的值。【同济大学2003四(10分)】【武汉大学2000五】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:二叉树顺序存储,是按完全二叉树的格式存储,利用完全二叉树双亲结点与子女结点编号间的关系进行求解。设结点值为x和y的两个结点的下标分别是i和j,求下标为i和j的双亲,

双亲的双亲,等等,直至找到最近的公共祖先。while(i!=j) //直到i=j时,就是原来两个结点的最近的公共祖先 if(i>j)i=i/2 ;//下标为x的结点的双亲结点的下标 else j=j/2;//下标为Y的结点的双亲结点的下标)

解析:

20.设一棵完全二叉树使用顺序存储在数组6f[1..n]中,请写出进行非递归的前序遍历算法。【西安电子

科技大学1998四(9分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:二叉树的顺序存储一般按完全二叉树的顺序存储格式,双亲与子女结点下标间有确定关系。顺序存储结构的二叉树用结点下标大于n(对于完全二叉树)或0(对一般二叉树的“虚结点”)来判空。本题是完全二叉树,核心语句段如下:while(i<=n||top>0) //初始调用时,i=1,top=0 {while(i<=n) fcout<<=n)S[++top]*2*i+1;//右子女的下标位置进栈i:2*i;//沿左子女向下} if(top>0)i=s[top 一一];//取出栈顶元素 })

解析:

21.若二叉树用以下存储结构表示,试给出求前序遍历的算法:TYPE Tree=ARRAY[1..max] OF RECORD data:

char ; parent:integer; END;【北京邮电大学2002五、4(15分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:另一种双亲表示法存储结构,结点结构是(dam,parent)。对每个结点,直接给出其双亲(的下标),用正或负表示该结点是双亲的右子女或左子女,0表示该结点是根,无双亲。该类结构不适于直接进行前序遍历(即若直接前序遍历,算法要很复杂),较好的办法是将这类结构转为结点及其左右子女的顺序存储结构。转换的核心语句段如下: for(i=1;i<=max; i++)(bt[i].1c=bt[i].rc=0;) //先将结点的左右子女初始化为0 for(i=1;i<=max; i++) //填入结点数据和结点左右子女的信息{bt[i].data=t[i].data;//t[]是原结构,bt[]是转换后的结构 if(t[i].parent0)

bt[t[i].parent].rc=i;//右子女 else root=i;//root记住根结点的下标 } 前序递归和非递归遍历上面已有,不再赘述。这类问题的求解方法值得注意。当给定数据存储结构不合适时,可由已给结构来构造好的数据结构,以便于运算。像上面第6题也是这样,先根据L和R数组,构造一个结点的双亲的数组T。)

解析:

22.设计算法返回二叉树T的先序序列的最后一个结点的指针,要求采用非递归形式,且不许用栈。【合肥工业大学1999五、2(8分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:二叉树先序序列最后一个结点的特征是:从根开始的任何结点,若有右子树,则是右子树中最右下的叶子结点;若无右子树,仅有左子树,则是左子树最右下的叶子结点。核心语句段如下:while(p) //设p是二叉树根结点的指针 f(p->rchild)p=p一>rchild;//若右子树不空,沿右子树向下else if(p一>1child)p=p一>lchild;//右子树空,左子树不空,沿左子树向下else return(p);//p即为所求)

解析:

23.已知一棵高度为k具有n个结点的二叉树,按顺序方式存储:(1)编写用先根遍历树中每个结点的非递归算法;(2)编写将树中最大序号叶子结点的祖先结点全部打印输出的算法。【东北大学1997六(20分)】(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:高度为K的二叉树,按顺序方式存储,要占用2 k一1个存储单元,与实际结点个数n关系不大,对不是完全二叉树的二叉树,要增加“虚结点”,使其在形态上成为完全二叉树。二叉树中最大序号的叶子结点是在顺序存储方式下编号最大的结点。核心语句段如下:while(bt[c]==0)c一一;//初值c=2 k一1,从后向前滤去虚结点找最大序号叶子f=c/2 ;//c的双亲结点f while(f!=0) //从结点c的双亲结点直到根结点,路径上所有结点均为祖先结点 {cout<cbt[f]);f=f/2 ;} //逆序输出,最老的祖先最后输出)

解析:

24.在二叉链表表示的二叉树中,增设一个指针域,初值为空,试给出算法在不使用堆栈又不破坏原二叉树的情况下,前序遍历该二叉树。【北京邮电大学2004五、2(15分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:将空指针(下面的pre)域改成指向双亲(或祖先)。核心语句段如下: while(t) //t初值是二叉树根结点的指针 {while(t) {cohtpre=f;//指向双亲,初值f=null f=t;t=t一>lchild;//沿左侧向下} t=f;//回退while(t&&t一>rchild==null) t=t 一>pre;//回返 if(t&&t一>rchild) {f=t一>pre;//避免从右侧返回时,再重复访问左侧 t=t 一>rchild;//右转 } })

解析:

25.对于二叉树的链接实现,完成非递归的中序遍历过程。【中山大学1999五、2(15分)】

(分数:2.00)

__________________________________________________________________________________________

正确答案:(正确答案:wh5.1e(p ||top>0) //p是二叉树指针,top是栈顶指针,初值为0 {while(p) {s[++top]=p;p=p一>lchild;) //沿左子树向下if(top)>0) {p=s[top一];coutrchild;)//退栈,访问,转右子树 })

解析:

26.T=A(D,E(#,,G)),

C(#,F(H,I))存储如上图。【北京邮电大学1999九(10分)】

(分数:2.00)

__________________________________________________________________________________________ 正确答案:(正确答案:二叉树用顺序方式存储,其遍历方法与用二叉链表方式存储类似。0表示空指针。顺序存储方式下,要告诉根结点的下标。 void InOrder(int i) //对顺序存储的二叉树进行中序遍历,i是根结点的下标 {if(i!=0) {InOrder(ar[i].Lc);//中序遍历左子树 cout<

解析:

27.试给出二叉树的自下而上、自右而左的层次遍历算法。【吉林大学2001二、2(8分)】

(分数:2.00)

__________________________________________________________________________________________ 正确答案:(正确答案:设一队列Q和栈S。将根结点入队。当队列不空,做如下操作:Q出队;出队元素入栈S;出队结点的非空左、右子女依次入队Q。队列空后,弹出栈S中元素即为所求。)

解析:

数据结构中二叉树中序遍历的教学分析

数据结构中二叉树中序遍历的教学分析 袁宇丽, 胡 玲 Ξ(内江师范学院计算机与信息科学系, 四川 内江 641112) 摘 要:数据结构的教学应注重方法的应用,在二叉树的中序遍历中使用投影法可以使遍历过程简单化, 再由其中的一种遍历递归算法(先序)推导得到另外两种(中序,后序)的遍历递归算法,让学生加深对整个遍 历过程的了解与掌握。 关键词:数据结构;二叉树;遍历;算法 中图分类号:G 642 文献标识码:A 文章编号:1671-1785(2006)04-0109-03 1 引言 《数据结构》是计算机学科的一门专业技术基础课,也是计算机程序设计的重要理论技术基础课。目的是在于让学生学会分析研究计算机加工的数据结构的特性,以便为应用涉及的数据结构选择适当的逻辑结构,存储结构及其相应的算法;并初步掌握算法的时间分析和空间分析的技术;培养学生进行复杂程序设计的能力和数据抽象的能力。但从学生角度而言,在学习该门课程时普遍反映较难,总觉得课程内容抽象,不易理解,好些具体算法不知从何下手。针对以上情况,任课教师在讲授该门课程时更应注重方法的应用,从多角度,多侧面展现知识点,化抽象为具体,化特殊为一般,不应只局限于教材上的一种解题模式,应结合自己的理解,补充新方法,这样才能更好的拓宽学生的思路,达到化难为易,举一反三的效果。下面以具体实例说明。 2 二叉树中序遍历的投影法 在二叉树的一些应用中,常常要求在树中查找具有某种特征的结点,或者对树中全部结点逐一进行某种处理。这就提出了一个遍历二叉树的问题,即如何按某条搜索路径巡访树中每个结点,使得每个结点均被访问一次,而且仅被访问一次。“访问”的含义很广,可以是对结点作各种处理,如输出结点的信息等。遍历对线性结构来说,是一个容易解决的问题。而对二叉树则不然,由于二叉树是一种非线性结构,每个结点都可能有两棵子树,因而需要寻找一种规律,以便使二叉树上的结点能排列在一个线性队列上,从而便于访问。 回顾二叉树的定义可知,二叉树是由三个基本单元组成:根结点、左子树、右子树。因此,若能依次遍历这三部分,便是遍历了整个二叉树。若限定先左后右的顺序,则分为三种情况:先(根)序遍历,中(根)序遍历,后(根)序遍历。二叉树的遍历及其应用是数据结构中一个很重要的知识点,要求学生能根据所给二叉树得到相应的三种遍历序列(前序,中序,后序),并能写出这三种遍历算法。以中序遍历而言,教材[1]结合图给出了中序遍历过程示意图,并具体分析了该遍历的递归执行过程。但递归调用及返回对学生来说本身就是一个较难掌握的知识,往往出现进入递归后不知怎样层层返回,所图1 二叉树 以书上在说明二叉树的中序遍历时借用递归调用与返回的 方法向学生展示整个遍历过程对初学者总感觉有一定难度。 我们在这里补充一种教材上没有提到的二叉树中序遍历的 直观方法:投影法。分析中序遍历的实质,是按先中序访问左子树,再访问根结点,最后中序访问右子树的顺序进行的。直 观上想,处于二叉树最左下方的结点应该是第一个要访问的结点,再结合二叉树本身的构造特点,是有严格的左右子树 之分的,所以投影法就是根据二叉树的结构特征得来的。对 于一棵二叉树,从根结点所在的层开始,将所有非空左子树 完全位于当前根结点的左方,将所有非空右子树完全位于当? 901?第21卷第4期N o 14V o l 121 内江师范学院学报JOU RNAL O F N E I J I AN G T EA CH ER S COLL EGE 收稿日期:2005-11-11  作者简介:袁字丽(1979-),女,四川自贡人,内江师范学院助教,硕士。

数据结构树和二叉树实验报告

《数据结构》课程实验报告 实验名称树和二叉树实验序号 5 实验日期 姓名院系班级学号 专业指导教师成绩 教师评语 一、实验目的和要求 (1)掌握树的相关概念,包括树、结点的度、树的度、分支结点、叶子结点、儿子结点、双亲结点、树 的深度、森林等定义。 (2)掌握树的表示,包括树形表示法、文氏图表示法、凹入表示法和括号表示法等。 (3)掌握二叉树的概念,包括二叉树、满二叉树和完全二叉树的定义。 (4)掌握二叉树的性质。 (5)重点掌握二叉树的存储结构,包括二叉树顺序存储结构和链式存储结构。 (6)重点掌握二叉树的基本运算和各种遍历算法的实现。 (7)掌握线索二叉树的概念和相关算法的实现。 (8)掌握哈夫曼树的定义、哈夫曼树的构造过程和哈夫曼编码产生方法。 (9)掌握并查集的相关概念和算法。 (10)灵活掌握运用二叉树这种数据结构解决一些综合应用问题。 二、实验项目摘要 1.编写一程序,实现二叉树的各种基本运算,并在此基础上设计一个主程序完成如下功能: (1)输出二叉树b; (2)输出H结点的左、右孩子结点值; (3)输出二叉树b的深度; (4)输出二叉树b的宽度; (5)输出二叉树b的结点个数; (6)输出二叉树b的叶子结点个数。 2.编写一程序,实现二叉树的先序遍历、中序遍历和后序遍历的各种递归和非递归算法,以及层次遍历的算法。 三、实验预习内容 二叉树存储结构,二叉树基本运算(创建二叉树、寻找结点、找孩子结点、求高度、输出二叉树)

三、实验结果与分析 7-1 #include #include #define MaxSize 100 typedef char ElemType; typedef struct node { ElemType data; struct node *lchild; struct node *rchild; } BTNode; void CreateBTNode(BTNode *&b,char *str) { BTNode *St[MaxSize],*p=NULL; int top=-1,k,j=0; char ch; b=NULL; ch=str[j]; while (ch!='\0') { switch(ch) { case '(':top++;St[top]=p;k=1; break; case ')':top--;break; case ',':k=2; break; default:p=(BTNode *)malloc(sizeof(BTNode)); p->data=ch;p->lchild=p->rchild=NULL; if (b==NULL) b=p; else { switch(k) { case 1:St[top]->lchild=p;break; case 2:St[top]->rchild=p;break; } } } j++; ch=str[j]; }

《数据结构》习题集:_树和叉树

第6章树和二叉树 一、选择题 1.有一“遗传”关系,设x是y的父亲,则x可以把它的属性遗传给y,表示该遗传关系最适合的数据结构是( B ) A、向量 B、树 C、图 D、二叉树 2.树最适合用来表示( B ) A、有序数据元素 B、元素之间具有分支层次关系的数据 C、无序数据元素 D、元素之间无联系的数据 3.树B 的层号表示为1a,2b,3d,3e,2c,对应于下面选择的( C ) A、1a(2b(3d,3e),2c) B、a(b(D,e),c) C、a(b(d,e),c) D、a(b,d(e),c) 4.对二叉树的结点从1 开始连续编号,要求每个结点的编号大于其左、右孩子的编号,同一结点的左右孩子中, 其左孩子的编号小于其右孩子的编号,则可采用( C )次序的遍历实现二叉树的结点编号。 A、先序 B、中序 C、后序 D、从根开始按层次遍历 5.按照二叉树的定义,具有3 个结点的二叉树有(C )种。 A、3 B、4 C、5 D、6 6.在一棵有n个结点的二叉树中,若度为2的结点数为n2,度为1的结点数为n1,度为0的结点数为n0,则树的最大高 度为( E ),其叶结点数为( H );树的最小高度为( B ),其叶结点数为( G );若采用链表存储结构,则有( I )个空链域。 log+1 C、log2n D、n A、n/2 B、??n2 E、n0+n1+n2 F、n1+n2 G、n2+1 H、1 I、n+1 J、n1K、n2L、n1+1 7.对一棵满二叉树,m 个树叶,n 个结点,深度为h,则( D ) A、n=m+h B、h+m=2n C、m=h-1 D、n=2h-1 8.设高度为h 的二叉树中只有度为0 和度为2 的结点,则此类二叉树中所包含的结点数至少为( B ),至多 为(D )。 A、2h B、2h-1 C、2h-1 D、2h-1 9.在一棵二叉树上第5 层的结点数最多为(B)(假设根结点的层数为1) A、8 B、16 C、15 D、32 10.深度为5 的二叉树至多有( C )个结点。 A、16 B、32 C、31 D、10 11.一棵有124 个叶结点的完全二叉树,最多有(B )个结点 A、247 B、248 C、249 D、250 12.含有129 个叶子结点的完全二叉树,最少有( D )个结点 A、254 B、255 C、256 D、257 13.假定有一棵二叉树,双分支结点数为15,单分支结点数为30,则叶子结点数为( B )个。 A、15 B、16 C、17 D、47 14.用顺序存储的方法将完全二叉树中所有结点逐层存放在数组R[1…n]中,结点R[i]若有左子树,则左子树是结 点( B )。 A、R[2i+1] B、R[2i] C、R[i/2] D、R[2i-1]

数据结构二叉树习题含答案

2.1 创建一颗二叉树 创建一颗二叉树,可以创建先序二叉树,中序二叉树,后序二叉树。我们在创建的时候为了方便,不妨用‘#’表示空节点,这时如果先序序列是:6 4 2 3 # # # # 5 1 # # 7 # #,那么创建的二叉树如下: 下面是创建二叉树的完整代码:穿件一颗二叉树,返回二叉树的根 2.2 二叉树的遍历 二叉树的遍历分为:先序遍历,中序遍历和后序遍历,这三种遍历的写法是很相似的,利用递归程序完成也是灰常简单的: 2.3 层次遍历 层次遍历也是二叉树遍历的一种方式,二叉树的层次遍历更像是一种广度优先搜索(BFS)。因此二叉树的层次遍历利用队列来完成是最好不过啦,当然不是说利用别的数据结构不能完成。 2.4 求二叉树中叶子节点的个数 树中的叶子节点的个数= 左子树中叶子节点的个数+ 右子树中叶子节点的 个数。利用递归代码也是相当的简单, 2.5 求二叉树的高度 求二叉树的高度也是非常简单,不用多说:树的高度= max(左子树的高度,右子树的高度) + 1 2.6 交换二叉树的左右儿子 交换二叉树的左右儿子,可以先交换根节点的左右儿子节点,然后递归以左右儿子节点为根节点继续进行交换。树中的操作有先天的递归性。。 2.7 判断一个节点是否在一颗子树中 可以和当前根节点相等,也可以在左子树或者右子树中。 2.8 求两个节点的最近公共祖先 求两个节点的公共祖先可以用到上面的:判断一个节点是否在一颗子树中。(1)如果两个节点同时在根节点的右子树中,则最近公共祖先一定在根节点的右子树中。(2)如果两个节点同时在根节点的左子树中,则最近公共祖先一定在根节点的左子树中。(3)如果两个节点一个在根节点的右子树中,一个在根节点的

数据结构二叉树实验报告

实验三二叉树的遍历 一、实验目的 1、熟悉二叉树的结点类型和二叉树的基本操作。 2、掌握二叉树的前序、中序和后序遍历的算法。 3、加深对二叉树的理解,逐步培养解决实际问题的编程能力。 二、实验环境 运行C或VC++的微机。 三、实验内容 1、依次输入元素值,以链表方式建立二叉树,并输出结点的值。 2、分别以前序、中序和后序遍历二叉树的方式输出结点内容。 四、设计思路 1. 对于这道题,我的设计思路是先做好各个分部函数,然后在主函数中进行顺序排列,以此完成实验要求 2.二叉树采用动态数组 3.二叉树运用9个函数,主要有主函数、构建空二叉树函数、建立二叉树函数、访问节点函数、销毁二叉树函数、先序函数、中序函数、后序函数、范例函数,关键在于访问节点 五、程序代码 #include #include #include #define OK 1 #define ERROR 0 typedef struct TNode//结构体定义 {

int data; //数据域 struct TNode *lchild,*rchild; // 指针域包括左右孩子指针 }TNode,*Tree; void CreateT(Tree *T)//创建二叉树按,依次输入二叉树中结点的值 { int a; scanf("%d",&a); if(a==00) // 结点的值为空 *T=NULL; else // 结点的值不为空 { *T=(Tree)malloc(sizeof(TNode)); if(!T) { printf("分配空间失败!!TAT"); exit(ERROR); } (*T)->data=a; CreateT(&((*T)->lchild)); // 递归调用函数,构造左子树 CreateT(&((*T)->rchild)); // 递归调用函数,构造右子树 } } void InitT(Tree *T)//构建空二叉树 { T=NULL; } void DestroyT(Tree *T)//销毁二叉树 { if(*T) // 二叉树非空 { DestroyT(&((*T)->lchild)); // 递归调用函数,销毁左子树 DestroyT(&((*T)->rchild)); // 递归调用函数,销毁右子树 free(T); T=NULL; } } void visit(int e)//访问结点 { printf("%d ",e); }

数据结构 二叉树练习题答案

数据结构第6章树和二叉树 一、下面是有关二叉树的叙述,请判断正误 (√)1.若二叉树用二叉链表作存贮结构,则在n个结点的二叉树链表中只有n-1个非空指针域。 n个结点的二叉树有n-1条分支 (×)2.二叉树中每个结点的两棵子树的高度差等于1。 (√)3.二叉树中每个结点的两棵子树是有序的。 (×)4.二叉树中每个结点有两棵非空子树或有两棵空子树。 (×)5.二叉树中每个结点的关键字值大于其左非空子树(若存在的话)所有结点的关键字值,且小于其右非空子树 (若存在的话)所有结点的关键字值。 (应当是二叉排序树的特点) (×)6.二叉树中所有结点个数是2k-1-1,其中k是树的深度。(应2k-1) (×)7.二叉树中所有结点,如果不存在非空左子树,则不存在非空右子树。 (×)8.对于一棵非空二叉树,它的根结点作为第一层,则它的第i层上最多能有2i -1个结点。

(应2i-1) (√)9.用二叉链表法(link-rlink)存储包含n个结点的二叉树,结点的2n个指针区域中有n+1个为空指针。(用二叉链表存储包含n个结点的二叉树,结点共有2n个链域。由于二叉树中,除根结点外,每一个结点有且仅有一个双亲,所以只有n-1个结点的链域存放指向非空子女结点的指针,即有后继链接的指针仅n-1个,还有n+1个空指针。)采用二叉链表存储有2n个链域,空链域为:2n-(n-1)=n+1 (√)10.具有12个结点的完全二叉树有5个度为2的结点。 最快方法:用叶子数=[ n/2] =6,再求n2=n0-1=5 [n/2] 除的结果四舍五入 二、填空 1.由3个结点所构成的二叉树有5种形态。 2. 一棵深度为6的满二叉树有n1+n2=0+ n2= n0-1=31 个分支结点和26-1 =32个叶子。 注:满二叉树没有度为1的结点,所以分支结点数就是二度结点数。 (或:总结点数为n=2k-1=26-1=63,叶子数为n0= [ n/2] =32,满二叉数没有度为1的结点,由n0=n2+1得n2=n0-1=32-1=31)

第六章树和二叉树习题数据结构

习题六树和二叉树 一、单项选择题 1.以下说法错误的是 ( ) A.树形结构的特点是一个结点可以有多个直接前趋 B.线性结构中的一个结点至多只有一个直接后继 C.树形结构可以表达(组织)更复杂的数据 D.树(及一切树形结构)是一种"分支层次"结构 E.任何只含一个结点的集合是一棵树 2.下列说法中正确的是 ( ) A.任何一棵二叉树中至少有一个结点的度为2 B.任何一棵二叉树中每个结点的度都为2 C.任何一棵二叉树中的度肯定等于2 D.任何一棵二叉树中的度可以小于2 3.讨论树、森林和二叉树的关系,目的是为了() A.借助二叉树上的运算方法去实现对树的一些运算 B.将树、森林按二叉树的存储方式进行存储 C.将树、森林转换成二叉树 D.体现一种技巧,没有什么实际意义 4.树最适合用来表示 ( ) A.有序数据元素 B.无序数据元素 C.元素之间具有分支层次关系的数据 D.元素之间无联系的数据 5.若一棵二叉树具有10个度为2的结点,5个度为1的结点,则度为0的结点个数是()A.9 B.11 C.15 D.不确定 6.设森林F中有三棵树,第一,第二,第三棵树的结点个数分别为M1,M2和M3。与森林F对应的二叉树根结点的右子树上的结点个数是()。 A.M1 B.M1+M2 C.M3 D.M2+M3 7.一棵完全二叉树上有1001个结点,其中叶子结点的个数是() A. 250 B. 500 C.254 D.505 E.以上答案都不对 8. 设给定权值总数有n 个,其哈夫曼树的结点总数为( ) A.不确定 B.2n C.2n+1 D.2n-1 9.二叉树的第I层上最多含有结点数为() A.2I B. 2I-1-1 C. 2I-1 D.2I -1 10.一棵二叉树高度为h,所有结点的度或为0,或为2,则这棵二叉树最少有( )结点A.2h B.2h-1 C.2h+1 D.h+1 11. 利用二叉链表存储树,则根结点的右指针是()。 A.指向最左孩子 B.指向最右孩子 C.空 D.非空 14.在二叉树结点的先序序列,中序序列和后序序列中,所有叶子结点的先后顺序()A.都不相同 B.完全相同 C.先序和中序相同,而与后序不同 D.中序和后序相同,而与先序不同 15.在完全二叉树中,若一个结点是叶结点,则它没()。 A.左子结点 B.右子结点 C.左子结点和右子结点 D.左子结点,右子结点和兄弟结点 16.在下列情况中,可称为二叉树的是()

目前最完整的数据结构1800题包括完整答案树和二叉树答案

第6章树和二叉树 部分答案解释如下。 12. 由二叉树结点的公式:n=n0+n1+n2=n0+n1+(n0-1)=2n0+n1-1,因为n=1001,所以1002=2n0+n1,在完全二叉树树中,n1只能取0或1,在本题中只能取0,故n=501,因此选E。 42.前序序列是“根左右”,后序序列是“左右根”,若要这两个序列相反,只有单支树,所以本题的A和B均对,单支树的特点是只有一个叶子结点,故C是最合适的,选C。A或B 都不全。由本题可解答44题。 47. 左子树为空的二叉树的根结点的左线索为空(无前驱),先序序列的最后结点的右线索为空(无后继),共2个空链域。 52.线索二叉树是利用二叉树的空链域加上线索,n个结点的二叉树有n+1个空链域。 部分答案解释如下。 6.只有在确定何序(前序、中序、后序或层次)遍历后,遍历结果才唯一。 19.任何结点至多只有左子树的二叉树的遍历就不需要栈。 24. 只对完全二叉树适用,编号为i的结点的左儿子的编号为2i(2i<=n),右儿子是2i+1(2i+1<=n) 37. 其中序前驱是其左子树上按中序遍历的最右边的结点(叶子或无右子女),该结点无右孩子。 38 . 新插入的结点都是叶子结点。 42. 在二叉树上,对有左右子女的结点,其中序前驱是其左子树上按中序遍历的最右边的结点(该结点的后继指针指向祖先),中序后继是其右子树上按中序遍历的最左边的结点(该结点的前驱指针指向祖先)。 44.非空二叉树中序遍历第一个结点无前驱,最后一个结点无后继,这两个结点的前驱线索和后继线索为空指针。 三.填空题

1.(1)根结点(2)左子树(3)右子树 2.(1)双亲链表表示法(2)孩子链表表示法(3)孩 子兄弟表示法 3.p->lchild==null && p->rchlid==null 4.(1) ++a*b3*4-cd (2)18 5.平衡 因子 6. 9 7. 12 8.(1)2k-1 (2)2k-1 9.(1)2H-1 (2)2H-1 (3)H=?log2N?+1 10. 用顺序存储二叉树时,要按完全二叉树的形式存储,非完全二叉树存储时,要加“虚结 点”。设编号为i和j的结点在顺序存储中的下标为s 和t ,则结点i和j在同一层上的条 件是?log2s?=?log2t?。 11. ?log2i?=?log2j?12.(1)0 (2)(n-1)/2 (3)(n+1)/2 (4) ?log2n?+1 13.n 14. N2+1 15.(1) 2K+1-1 (2) k+1 16. ?N/2? 17. 2k-2 18. 64 19. 99 20. 11 21.(1) n1-1 (2)n2+n3 22.(1)2k-2+1(第k层1个结点,总结点个数是2H-1,其双亲是2H-1/2=2k-2)(2) ?log2i?+1 23.69 24. 4 25.3h-1 26. ?n/2? 27. ?log2k?+1 28.(1)完全二叉树 (2)单枝树,树中任一结点(除最后一个结点是叶子外),只有左子女或 只有右子女。 29.N+1 30.(1) 128(第七层满,加第八层1个) (2) 7 31. 0至多个。任意二叉树,度为1的结点个数没限制。只有完全二叉树,度为1的结点个 数才至多为1。 32.21 33.(1)2 (2) n-1 (3) 1 (4) n (5) 1 (6) n-1 34.(1) FEGHDCB (2)BEF(该二叉树转换成森林,含三棵树,其第一棵树的先根次序是 BEF) 35.(1)先序(2)中序 36. (1)EACBDGF (2)2 37.任何结点至多只有右子女 的二叉树。 38.(1)a (2) dbe (3) hfcg 39.(1) . (2) ...GD.B...HE..FCA 40.DGEBFCA 41.(1)5 (2)略 42.二叉排序树 43.二叉树 44. 前序 45.(1)先根次序(2)中根次序46.双亲的右子树中最左下的叶子结点47.2 48.(n+1)/2 49.31(x的后继是经x的双亲y的右子树中最左下的叶结点) 50.(1)前驱 (2)后 继 51.(1)1 (2)y^.lchild (3)0 (4)x (5)1 (6) y (7)x(编者注:本题按 中序线索化) 52.带权路径长度最小的二叉树,又称最优二叉树 53.69 54.(1)6 (2)261 55.(1)80 (2)001(不唯一)56.2n0-1 57.本题①是表达式求值,②是在二叉排序树中删除值为x的结点。首先查找x,若没有x, 则结束。否则分成四种情况讨论:x结点有左右子树;只有左子树;只有右子树和本身是叶 子。 (1)Postoder_eval(t^.Lchild) (2) Postorder_eval(t^.Rchild) (3)ERROR(无此运 算符)(4)A (5)tempA^.Lchild (6)tempA=NULL(7)q^.Rchild (8)q (9)tempA^.Rchild (10)tempA^.Item

数据结构树和二叉树习题

树与二叉树 一.选择题 1.假定在一棵二叉树中,双分支结点数为15,单分支结点数为30个,则叶子结 点数为()个。 A.15B.16C.17D.47 2.按照二叉树的定义,具有3个结点的不同形状的二叉树有()种。 A. 3 B. 4 C. 5 D. 6 3.按照二叉树的定义,具有3个不同数据结点的不同的二叉树有()种。 A. 5 B. 6 C. 30 D. 32 4.深度为5的二叉树至多有()个结点。1 A. 16 B. 32 C. 31 D. 10 5.设高度为h的二叉树上只有度为0和度为2的结点,则此类二叉树中所包含的 结点数至少为()。 A. 2h B. 2h-1 C. 2h+1 D. h+1 6.对一个满二叉树2,m个树叶,n个结点,深度为h,则()。 A. n=h+m3 B. h+m=2n C. m=h-1 D. n=2 h-1 1深度为n的二叉树结点至多有2n-1 2满二叉树是除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树7.任何一棵二叉树的叶结点在先序.中序和后序遍历序列中的相对次序()。 A.不发生改变 B.发生改变 C.不能确定 D.以上都不对 8.如果某二叉树的前根次序遍历结果为stuwv,中序遍历为uwtvs,那么该二叉 树的后序为()。 A. uwvts B. vwuts C. wuvts D. wutsv 9.某二叉树的前序遍历结点访问顺序是abdgcefh,中序遍历的结点访问顺序是 dgbaechf,则其后序遍历的结点访问顺序是()。 A. bdgcefha B. gdbecfha C. bdgaechf D. gdbehfca 10.在一非空二叉树的中序遍历序列中,根结点的右边()。 A. 只有右子树上的所有结点 B. 只有右子树上的部分结点 C. 只有左子树上的部分结点 D. 只有左子树上的所有结点 11.树的基本遍历策略可分为先根遍历和后根遍历;二叉树的基本遍历策略可分为 先序遍历.中序遍历和后序遍历。这里,我们把由树转化得到的二叉树4叫做这棵数对应的二叉树。结论()是正确的。 A.树的先根遍历序列与其对应的二叉树的先序遍历序列相同 B.树的后根遍历序列与其对应的二叉树的后序遍历序列相同 3对于深度为h的满二叉树,n=20+21+…+2h-1=2h-1,m=2h-1。故而n=h+m。 4树转化为二叉树的基本方法是把所有兄弟结点都用线连起来,然后去掉双亲到子女的连线,只留下双亲到第一个子女的连线。因此原来的兄弟关系就变为双亲与右孩子的关系。 1/ 9

数据结构实验报告-二叉树的实现与遍历

《数据结构》第六次实验报告 学生姓名 学生班级 学生学号 指导老师

一、实验内容 1) 采用二叉树链表作为存储结构,完成二叉树的建立,先序、中序和后序 以及按层次遍历的操作,求所有叶子及结点总数的操作。 2) 输出树的深度,最大元,最小元。 二、需求分析 遍历二叉树首先有三种方法,即先序遍历,中序遍历和后序遍历。 递归方法比较简单,首先获得结点指针如果指针不为空,且有左子,从左子递归到下一层,如果没有左子,从右子递归到下一层,如果指针为空,则结束一层递归调用。直到递归全部结束。 下面重点来讲述非递归方法: 首先介绍先序遍历: 先序遍历的顺序是根左右,也就是说先访问根结点然后访问其左子再然后访问其右子。具体算法实现如下:如果结点的指针不为空,结点指针入栈,输出相应结点的数据,同时指针指向其左子,如果结点的指针为空,表示左子树访问结束,栈顶结点指针出栈,指针指向其右子,对其右子树进行访问,如此循环,直至结点指针和栈均为空时,遍历结束。 再次介绍中序遍历: 中序遍历的顺序是左根右,中序遍历和先序遍历思想差不多,只是打印顺序稍有变化。具体实现算法如下:如果结点指针不为空,结点入栈,指针指向其左子,如果指针为空,表示左子树访问完成,则栈顶结点指针出栈,并输出相应结点的数据,同时指针指向其右子,对其右子树进行访问。如此循环直至结点指针和栈均为空,遍历结束。 最后介绍后序遍历: 后序遍历的顺序是左右根,后序遍历是比较难的一种,首先需要建立两个栈,一个用来存放结点的指针,另一个存放标志位,也是首先访问根结点,如果结点的指针不为空,根结点入栈,与之对应的标志位也随之入标志位栈,并赋值0,表示该结点的右子还没有访问,指针指向该结点的左子,如果结点指针为空,表示左子访问完成,父结点出栈,与之对应的标志位也随之出栈,如果相应的标志位值为0,表示右子树还没有访问,指针指向其右子,父结点再次入栈,与之对应的标志位也入栈,但要给标志位赋值为1,表示右子访问过。如果相应的标志位值为1,表示右子树已经访问完成,此时要输出相应结点的数据,同时将结点指针赋值为空,如此循环直至结点指针和栈均为空,遍历结束。 三、详细设计 源代码:

数据结构实验-二叉树的操作

******************************* 实验题目:二叉树的操作 实验者信息:班级13007102,姓名庞文正,学号1300710226 实验完成的时间3:00 ****************************** 一、实验目的 1,掌握二叉树链表的结构和二叉树的建立过程。 2,掌握队列的先进先出的运算原则在解决实际问题中的应用。 3,进一步掌握指针变量、指针数组、动态变量的含义。 4,掌握递归程序设计的特点和编程方法。 二、实验内容 已知以二叉链表作存储结构,试编写按层次遍历二叉树的算法。(所谓层次遍历,是指从二叉树的根结点开始从上到下逐层遍历二叉树,在同一层次中从左到右依次访问各个节点。)调试程序并对相应的输出作出分析;修改输入数据,预期输出并验证输出的结果。加深对算法的理解。 三、算法设计与编码 1.本实验用到的理论知识 总结本实验用到的理论知识,实现理论与实践相结合。总结尽量简明扼要,并与本次实验密切相关,最好能加上自己的解释。 本算法要采用一个循环队列que,先将二叉树根结点入队列,然后退队列,输出该结点;若它有左子树,便将左子树根结点入队列;若它有右子树,便将右子树根结点入队列,直到队列空为止。因为队列的特点是先进先出,从而达到按层次顺序遍历二叉的目的。2.算法概要设计 给出实验的数据结构描述,程序模块、功能及调用关系 #include #include #define M 100 typedef struct node //二叉链表节点结构 {int data; //数据域 struct node *lchild,*rchild; //左孩子右孩子链 }bitree; bitree *que[M]; //定义一个指针数组,说明队列中的元素bitree 指针类型 int front=0, rear=0; //初始化循环列队 bitree *creat() //建立二叉树的递归算法 {bitree *t; int x; scanf("%d",&x); if(x==0) t=NULL; //以x=0 表示输入结束 else {t=malloc(sizeof(bitree)); //动态生成节点t,分别给节点t 的数据域,t->data=x; //左右孩子域赋值,给左右孩子赋值时用到 t->lchild=creat(); // 了递归思想 t->rchild=creat(); }

数据结构之二叉树概述

数据结构之二叉树 第一篇:数据结构之链表 第二篇:数据结构之栈和队列 在这篇文章里面,我们主要探讨和树相关的话题。 首先,我们来对树进行定义:树是n(n>= 0)个节点的有限集。在任何一个非空树中:(1)有且仅有一个特定的称为“根”的节点;(2)当n>1时,其余节点可分为m(m>0)个互相相关的有限集T1、T2、T3……,其中每一个集合本身又是一棵树,并且称为根的子树。 对于我们这篇文章里讨论的二叉树,它是一种特殊的树形结构,每个节点至多只有两颗子树,并且子树有左右之分,其次序不能随意颠倒。 接下来,我们使用java代码来定义一棵树: 1public class BinNode { 2private int m_Value; 3private BinNode m_Left; 4private BinNode m_Right; 5public void setValue(int m_Value) { 6this.m_Value = m_Value; 7 } 8public int getValue() { 9return m_Value; 10 } 11public void setLeft(BinNode m_Left) { 12this.m_Left = m_Left; 13 } 14public BinNode getLeft() { 15return m_Left; 16 } 17public void setRight(BinNode m_Right) { 18this.m_Right = m_Right; 19 } 20public BinNode getRight() { 21return m_Right; 22 } 23 24public boolean isLeaf() 25 { 26return m_Left == null && m_Right == null; 27 } 28 }

数据结构实验报告之树与二叉树

学生实验报告 学院:软通学院 课程名称:数据结构与算法 专业班级:软件142 班 姓名:邹洁蒙 学号: 0143990

学生实验报告 (二) 一、实验综述 1、实验目的及要求 目的:1)掌握树与二叉树的基本概念; 2)掌握二叉树的顺序存储,二叉链表的先序遍历中序遍历和后序遍历算法; 3)掌握树的双亲表示法。 要求:1)编程:二叉树的顺序存储实现; 2)编程:二叉链表的先序遍历中序遍历和后序遍历实现; 3)编程:树的双亲表示法实现。 2、实验仪器、设备或软件 设备:PC 软件:VC6 二、实验过程(编程,调试,运行;请写上源码,要求要有注释) 1.编程:二叉树的顺序存储实现 代码: BiTree::BiTree()//建立存储空间 { data = new int[MAXSIZE]; count = 0; } void BiTree::AddNode(int e)//加结点 { int temp = 0; data[count] = e; count++;//从编号0开始保存 }

运行截图: 2.编程:二叉链表的先序遍历中序遍历和后序遍历实现代码: void InOrderTraverse(BiTree* Head)//中序遍历 { if (Head) { InOrderTraverse(Head->LeftChild); cout << Head->data<<" "; InOrderTraverse(Head->RightChild); } } void PreOrderTraverse(BiTree* Head)//先序遍历 { if (Head) { cout << Head->data << " "; PreOrderTraverse(Head->LeftChild); PreOrderTraverse(Head->RightChild); } } void PostOrderTraverse(BiTree* Head)//后序遍历 { if (Head) { PostOrderTraverse(Head->LeftChild); PostOrderTraverse(Head->RightChild); cout << Head->data << " "; } } 运行截图:

数据结构实验报告—二叉树

算法与数据结构》课程实验报告

一、实验目的 1、实现二叉树的存储结构 2、熟悉二叉树基本术语的含义 3、掌握二叉树相关操作的具体实现方法 二、实验内容及要求 1. 建立二叉树 2. 计算结点所在的层次 3. 统计结点数量和叶结点数量 4. 计算二叉树的高度 5. 计算结点的度 6. 找结点的双亲和子女 7. 二叉树前序、中序、后序遍历的递归实现和非递归实现及层次遍历 8. 二叉树的复制 9. 二叉树的输出等 三、系统分析 (1)数据方面:该二叉树数据元素采用字符char 型,并且约定“ #”作为二叉树输入结束标识符。并在此基础上进行二叉树相关操作。 (2)功能方面:能够实现二叉树的一些基本操作,主要包括: 1. 采用广义表建立二叉树。 2. 计算二叉树高度、统计结点数量、叶节点数量、计算每个结点的度、结点所在层次。 3. 判断结点是否存在二叉树中。 4. 寻找结点父结点、子女结点。 5. 递归、非递归两种方式输出二叉树前序、中序、后序遍历。 6. 进行二叉树的复制。 四、系统设计 (1)设计的主要思路 二叉树是的结点是一个有限集合,该集合或者为空,或者是由一个根节点加上两棵分别称为左子树和右子树、互不相交的二叉树组成。根据实验要求,以及课上老师对于二叉树存储结构、基本应用的讲解,同时课后研究书中涉及二叉树代码完成二叉树模板类,并将所需实现各个功能代码编写完成,在建立菜单对功能进行调试。 (2)数据结构的设计 二叉树的存储结构有数组方式和链表方式。但用数组来存储二叉树有可能会消耗大量的存储空间,故在此选用链表存储,提高存储空间的利用率。根据二叉树的定义,二叉

数据结构实验-二叉树的操作

******************************* 实验题目:二叉树的操作 实验者信息:班级 13007102,姓名 庞文正,学号 1300710226 实验完成的时间 3:00 ****************************** 一、 实验目的 1, 掌握二叉树链表的结构和二叉树的建立过程。 2, 掌握队列的先进先出的运算原则在解决实际问题中的应用。 3, 进一步掌握指针变量、指针数组、动态变量的含义。 4, 掌握递归程序设计的特点和编程方法。 二、 实验内容 已知以二叉链表作存储结构,试编写按层次遍历二叉树的算法。 (所谓层次遍历,是 指从二叉树的根结点开始从上到下逐层遍历二叉树, 在同一层次中从左到右依次访问各个节 点。)调试程序并对相应的输出作出分析;修改输入数据,预期输出并验证输出的结果。加 深对算法的理解。 三、 算法设计与编码 1. 本实验用到的理论知识 总结本实验用到的理论知识, 实现理论与实践相结合。 总结尽量简明扼要, 并与本次实验密 切相关,最好能加上自己的解释。 本算法要采用一个循环队列 que,先将二叉树根结点入队列,然后退队列,输出该 结点;若它 有左子树,便将左子树根结点入队列; 若它有右子树,便将右子树根结点入队列, 直到队列空为止。因为队列的特点是先进先出,从而达到按层次顺序遍历二叉的目的。 2. 算法概要设计 给出实验的数据结构描述,程序模块、功能及调用关系 #include #include #define M 100 typedef struct node //二叉链表节点结构 {int data; // 数据域 struct node *lchild,*rchild; }bitree; bitree *que[M]; //定义一个指针数组,说明队列中的元素 int front=0, rear=0; 〃初始化循环列队 bitree *creat() 〃建立二叉树的递归算法 {bitree *t; int x; scanf("%d”,&x); if(x==0) t=NULL; 〃以 else {t=malloc(sizeof(bitree)); t->data=x; t->lchild=creat(); t->rchild=creat(); //左孩子右孩子链 x=0表示输入结束 bitree 指针类型 〃动态生成节点t,分别给节点t 的数据域, //左右孩子域赋值,给左右孩子赋值时用到 // 了递归思想

数据结构—— 树和二叉树知识点归纳

第6章树和二叉树 6.1 知识点概述 树(Tree)形结构是一种很重要的非线性结构,它反映了数据元素之间的层次关系和分支关系。在计算机科学中具有广泛的应用。 1、树的定义 树(Tree)是n(n≥0)个数据元素的有限集合。当n=0时,称这棵树为空树。在一棵非空树T中: (1)有一个特殊的数据元素称为树的根结点,根结点没有前驱结点。 (2)若n>1,除根结点之外的其余数据元素被分成m(m>0)个互不相交的集合T1,T2,…,Tm,其中每一个集合Ti(1≤i≤m)本身又是一棵树。树T1,T2,…,Tm称为这个根结点的子树。 2、树的基本存储结构 (1)双亲表示法 由于树中的每一个结点都有一个唯一确定的双亲结点,所以我们可用一组连续的 存储空间(即一维数组)存储树中的结点。每个结点有两个域:一个是data域,存放结点信息,另一个是parent域,用来存放双亲的位置(指针)。 (2)孩子表示法 将一个结点所有孩子链接成一个单链表形,而树中有若干个结点,故有若干个单 链表,每个单链表有一个表头结点,所有表头结点用一个数组来描述这种方法通常是把每个结点的孩子结点排列起来,构成一个单链表,称为孩子链表。 (3)双亲孩子表示法 双亲表示法是将双亲表示法和孩子表示法相结合的结果。其仍将各结点的孩子结点分别组成单链表,同时用一维数组顺序存储树中的各结点,数组元素除了包括结点本身的信息和该结点的孩子结点链表的头指针之外,还增设一个域,存储该结点双亲结点在数组中的序号。 (4)孩子兄弟表示法 这种表示法又称为树的二叉表示法,或者二叉链表表示法,即以二叉链表作为树的存储结构。链表中每个结点设有两个链域,分别指向该结点的第一个孩子结点和下一个兄弟(右兄弟)结点。 3、二叉树的定义 二叉树(Binary Tree)是个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个结点。 4、满二叉树 定义:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子结点都在同一层上,这样的一棵二叉树称作满二叉树。 5、完全二叉树 定义:一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。完全二叉树的特点是:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。 6、二叉树的性质

数据结构实验二叉树

实验六:二叉树及其应用 一、实验目的 树是数据结构中应用极为广泛的非线性结构,本单元的实验达到熟悉二叉树的存储结构的特性,以及如何应用树结构解决具体问题。 二、问题描述 首先,掌握二叉树的各种存储结构和熟悉对二叉树的基本操作。其次,以二叉树表示算术表达式的基础上,设计一个十进制的四则运算的计算器。 如算术表达式:a+b*(c-d)-e/f 三、实验要求 如果利用完全二叉树的性质和二叉链表结构建立一棵二叉树,分别计算统计叶子结点的个数。求二叉树的深度。十进制的四则运算的计算器可以接收用户来自键盘的输入。由输入的表达式字符串动态生成算术表达式所对应的二叉树。自动完成求值运算和输出结果。四、实验环境 PC微机 DOS操作系统或 Windows 操作系统 Turbo C 程序集成环境或 Visual C++ 程序集成环境 五、实验步骤 1、根据二叉树的各种存储结构建立二叉树; 2、设计求叶子结点个数算法和树的深度算法; 3、根据表达式建立相应的二叉树,生成表达式树的模块; 4、根据表达式树,求出表达式值,生成求值模块; 5、程序运行效果,测试数据分析算法。 六、测试数据 1、输入数据:2.2*(3.1+1.20)-7.5/3 正确结果:6.96 2、输入数据:(1+2)*3+(5+6*7); 正确输出:56 七、表达式求值 由于表达式求值算法较为复杂,所以单独列出来加以分析: 1、主要思路:由于操作数是任意的实数,所以必须将原始的中缀表达式中的操作数、操作符以及括号分解出来,并以字符串的形式保存;然后再将其转换为后缀表达式的顺序,后缀表达式可以很容易地利用堆栈计算出表达式的值。 例如有如下的中缀表达式: a+b-c 转换成后缀表达式为: ab+c- 然后分别按从左到右放入栈中,如果碰到操作符就从栈中弹出两个操作数进行运算,最后再将运算结果放入栈中,依次进行直到表达式结束。如上述的后缀表达式先将a 和b 放入栈中,然后碰到操作符“+”,则从栈中弹出a 和b 进行a+b 的运算,并将其结果d(假设为d)放入栈中,然后再将c 放入栈中,最后是操作符“-”,所以再弹出d和c 进行d-c 运算,并将其结果再次放入栈中,此时表达式结束,则栈中的元素值就是该表达式最后的运算结果。当然将原始的中缀表达式转换为后缀表达式比较关键,要同时考虑操作符的优先级以及对有括号的情况下的处理,相关内容会在算法具体实现中详细讨论。

相关文档
最新文档