当前位置:文档之家› 构建二叉树的二叉链表存储结构

构建二叉树的二叉链表存储结构

二叉树的二叉链表存储结构构建方法假设有关二叉树的二叉链表存储的类型定义如下:

typedef struct BiTNode{ // 结点结构

ElemType data ;//数据域

struct BiTNode *Lchild ;//左孩子指针

struct BiTNode *Rchild;//右孩子指针

} BiTNode ,*BiTree ;

1 利用扩展二叉树的先序序列构建

只根据二叉树的先序序列是不能唯一确定一棵二叉树的。针对这一问题,可做如下处理:对二叉树中每个结点的空指针引出一个虚结点,设其值为#,表示为空,把这样处理后的二叉树称为原二叉树的扩展二叉树。扩展二叉树的先序序列可唯一确定这棵二叉树。如图 1 所示,给出了一棵二叉树的扩展二叉树,以及该扩展二叉树的先序序列。

建立二叉链表的算法如下:

void Create(BiTree &T)

{//输入扩展二叉树的先序序列,构建二叉链表scanf(&ch); //输入一个元素

if (ch=='# ') T = NULL;

else

{ T= (BiTree)malloc(sizeof(BiTNode));

//申请根结点

T->data =ch; // 给根结点数据域赋值

Create(T->Lchild);//建左子树

Create(T->Rchild);//建右子树

}

} // Create

2 利用二叉树的先序序列和中序序列

容易证明:由一棵二叉树的先序序列和中序序列可唯一的确定一棵二叉树。

基本思想:先根据先序序列的第一个元素建立根结点;然后在中序序列中找到该元素,确定根结点的左、右子树的中序序列;根据左、右子树的中序序列确定左、右子树中结点的个数;再根据结点个数在先序序列中确定左、右子树的先序序列;最后由左子树的先序序列与中序序列建立左子树,由右子树的先序序列与中序序列建立右子树。

显然,这是一个递归过程。假设先序序列放在数组pre[0..n-1]中,中序序列放在数组mid[0..n-1]中,n是二叉树中元素的个数,其算法如下:

int Find(ElemType *P, int L2 ,int H2, ElemType x)

{//在数组P的区间L2..H2内确定x的位置

i=L2;

while(P[i]!=x) i++;

return i;

}// Find

void Create (BiTree &T, int L1, int H1, int L2, int H2)

{//已知先序序列pre[L1..H1],

//中序序列mid[L2..H2]构建二叉链表

if (L2>H2) T=NULL; //建空树

else

{ T =(BiTree)malloc(sizeof(BiTNode));

//创建根结点T

T ->data=pre[L1]; //给根数据域赋值

k=Find(mid, L2, H2, pre[L1]);

//找根在中序序列的位置

Create (T ->Lchild, L1+1,k+L1-L2, L2,k-1);

//创建左子树

Create(T->Rchild,k+L1-L2+1,H1,k+1, H2);

//创建右子树

}

}// Create

3 利用扩展完全二叉树的顺序存储

约定对二叉树上的结点从根结点起,自上而下,自左而右进行连续编号,根结点的编号为1。深度为k的,有n个结点的二叉树,当且仅当其每个结点的编号都与深度为k的满二叉树中编号为1至n中的结点一一对应时,称其为完全二叉树。

如果一棵二叉树不是完全二叉树,可以用添加虚结点的方式将其扩展为一棵完全二叉树,虚结点的值设为#

,表示该结点不存在,把这样处

理后的二叉树称为原二叉树的扩展完全二叉树。如图2中的(a)不是完全二叉树,(b)为(a)的扩展完全二叉树。

完全二叉树的性质[2]:如果一棵完全二叉树有n个结点,则有:1)编号为i的结点如果有左孩子,则左孩子的编号为2i;2)如果有右孩子,则右孩子的编号为2i+1。

基本思想:1)将二叉树扩展为一棵完全二叉树;2)根据编号将结点的值依次放在数组s 的s[1..n]中。3)根据完全二叉树的性质,构造二叉树的二叉链表存储结构。这里n为扩展完全二叉树的结点个数,如图2中的n 为11。

对于第3)步,s[1]是二叉树的根结点,如果2<=n则s[2]是s[1]的左孩子,否则左孩子为空;如果3<=n则s[3]是s[1]的右孩子,否则右孩子为空;一般的,对于s[i]:

if (s[i]== '#' ) then 建空树;

else { if (2i<=n) then s[2i]是s[i]的左孩子else 左孩子为空;

if (2i+1<=n) then s[2i+1]是s[i]的右孩子;

else 右孩子为空; }

显然,这是一个递归过程。其算法如下:void Create (Bitree &T , ElemType *s, int i, int n) {//创建一棵以s[i]值为根的值的二叉树的二

//叉链表,树的根为T

if(s[i]=='#') T =NULL;

else

{ T =(BiTree)malloc(*sizeof(BiTNode));

//申请根结点

T ->data=s[i];

// 给根结点的数据域赋值

j=2*i;

if (j<=n) //创建左子树

Create (T->Lchild , s, j, n);

else T->Lchild=NULL;

j++;

if(j<=n) //创建右子树

Create (T ->Rchild , s, j, n);

else T ->Rchild=NULL;

}

}// Create

4 利用二叉排序树的性质

基本思想:从一棵空二叉树出发,按照先序序列依次插入各结点。假设先序列放在pre[1..n]中,中序序列放在mid[1..n]中,这里n是二叉树的结点个数。pre[1]是树的根,pre[i](i=2,3,…n)究竟插在左子树上还是右子树上,则要看pre[i]在中序序列中的位置,如果pre[i]在pre[1]的之前,则插入到左子树上,否则插在右子树上。为此可定义一个函数Find来确定结点在中序序列中的位置。

Find:pre[1..n] 1..n 定义如下:

如果pre[i]=mid[j] 则Find(pre[i])=j ;

这样,对于pre[1..n]中的每个元素(即树上的每个结点)都赋予了一个值,根据pre[1..n]和赋予每个元素pre[i](i=1,2…n)的Find(pre[i])值,按照构造二叉排序树的方法依次插入各结点,建立二叉树。其算法如下:

int Find (ElemType *mid , int n, ElemType x)

{//求x在中序序列中的位置

for( j=1;j<=n ; j++)

if(x==mid[j]) return j;

}// Find

void Insert_Node(Bitree &T , Bitree s) {//将s插在以T为根的二叉树的合适位置上

if (T==NULL) T=s; //在空树上插入s

else

{ if(Find(T->data)>Find(s->data))

//将s所指结点插在左子树上

Insert_Node(T->Lchild,s);

else //将s所指结点插在右子树上

Insert_Node(T->Rchild,s);

}// Insert_Node

void Create (Bitree &T, int n)

{//建有n个结点的二叉树的二叉链表

T=NULL; //先建立一棵空树

for(j=1;j<=n;j++)

{ //依次产生结点和插入结点

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

s ->data=pre[j];

s->Lchild=NULL;

s->Rchild=NULL;

Insert_Node(T,s);//插入s }

}// Create

数据结构二叉树实验报告

一 、实验目的和要求 (1)掌握树的相关概念,包括树、节点的度、树的度、分支节点、叶子节点、孩子节点、双亲节 点、树的深度、森林等定义。 (2)掌握树的表示,包括树形表示法、文氏图表示法、凹入表示法和括号表示法等。 (3)掌握二叉树的概念,包括二叉树、满二叉树和完全二叉树的定义。 (4)掌握二叉树的性质。 (5)重点掌握二叉树的存储结构,包括二叉树顺序存储结构和链式存储结构。 (6)重点掌握二叉树的基本运算和各种遍历算法的实现。 (7)掌握线索二叉树的概念和相关算法的实现。 (8)掌握哈夫曼树的定义、哈夫曼树的构造过程和哈夫曼编码的产生方法。 (9)掌握并查集的相关概念和算法。 (10)灵活运用二叉树这种数据结构解决一些综合应用问题。 二、实验内容 注:二叉树b 为如图7-123所示的一棵二叉树 图7-123+ 实验7.1 编写一个程序algo7-1.cpp,实现二叉树的各种运算,并在此基础上设计一个程序 exp7-1.cpp 完成如下功能: (1)输出二叉树b ; (2)输出H 节点的左、右孩子节点值; (3)输出二叉树b 的深度; (4)输出二叉树b 的宽度; (5)输出二叉树b 的节点个数; (6)输出二叉树b 的叶子节点个数。 实验7.2设计一个程序exp7-2.cpp,实现二叉树的先序遍历、中序遍历和后序遍历和非递归算法, 以及层次变量里的算法。并对图7-123所示的二叉树b 给出求解结果。 b+ A C F G I K L+ N M+ E+ Hd J D ₄ B

臣1607-1.CPP if(b?-HULL) re3P4+; Qu[rear]-p-b; Qu[rear].1no=1; while(reart=front) { Front++; b=Qu[front]-P; lnum-Qu[front].1no; if(b->Ichildt=NULL) rpar+t; Qu[rear]-p=b->1child; Qu[rear].Ino-lnun+1; if(D->rch11d?=NULL)1/根结点指针入队 //根结点的层次编号为1 1/队列不为空 1/队头出队 1/左孩子入队 1/右孩子入队 redr+t; qu[rear]-p=b->rchild; Qu[rear].1no-lnun*1; } } nax-0;lnun-1;i-1; uhile(i<=rear) { n=0; whdle(i<=rear ge Qu[1].1no==1num) n+t;it+; Inun-Qu[i].1n0; if(n>max)nax=n; } return max; 田1607-1.CPP return max; } else return o; 口× int Modes(BTNode *D) //求二叉树D的结点个数 int nun1,nun2; if(b==NULL) returng, else if(b->ichild==NULL&D->rchild==NULL) return 1; else { num1-Hodes(b->Ichild); num2=Nodes(b->rchild); return(num1+nun2+1); LeafNodes(BINode *D) //求二叉树p的叶子结点个数 int num1,num2; 1f(D==NULL) return 0; else if(b->1chi1d==NULLc& b->rch11d==NULL) return 1; else { num1-LeafModes(b->lchild); num2=LeafNodes(b->rchild); return(nun1+nun2); int

数据结构模拟试题三及答案

数据结构模拟试题三 一.判断题(每小题1 分,共10分) 1.逻辑结构不同的数据,要采用不同的存储方法来存储。 2.单链表中的结点只有后继,没有前驱。 3.栈和队列具有相同的逻辑特性。 4.二叉树中结点之间的相互关系不能用二元组来表示。 5.关键路径是由权值最大的边构成的。 6.在表示矩阵的三元组顺序表中,各元素的排列顺序与矩阵元素值的大小无关。 7.在广义表中,每个原子必须是单个字符。 8.在平衡二叉排序树中,每个结点的平衡因子值是相等的。 9.只有在线性表的初始状态为逆序排列的情况下,起泡排序过程中,元素的移动次数才会 达到最大值。 10.在B+树上可以进行顺序查找。 二.填空题(每空1分,共10分) 1.若用不带表头结点的单链表来表示链接队列,则只有在________情况下,插入操作既要 修改队尾指针的值,也要修改队头指针的值;只有在________情况下,删除操作仅需修改队首指针的值,不需修改队尾指针的值。 2.无向图中边的数目等于邻接矩阵中___________。 3.在各元素查找概率相等的情况下,在含有12个元素的二叉排序树上查找其中一个元素, 元素间的平均比较次数至少是____次,至多是____次。 4.对12个元素进行快速排序,排序码的比较次数最多是___次。 5.对B+树来说,若某个非根分支结点中有6个关键字,则在它的某个孩子结点中至少有 _____个关键字,至多有_____个关键字。 6.如果在根结点中要查到要找的关键字,则对于B-树来说,下一步应该_________,而对 于B+树来说,下一步应该_________。 三.单选题(每题2分,共20分) 1.线性结构采用链式存储,________。 A.对插入、删除结点的操作较为有利B.不利于进行顺序访问 C.逻辑上相邻的结点在存储器中也相邻D.可以用一些不连续的存储区域来存放一个结点2. 某算法的时间复杂度为O(2n),表明该算法的________。 A.执行时间与2n成正比B.执行时间等于2n C.问题规模是2n D.问题规模与2n成正比 3. 在长度为n的_________上,删除最后一个元素,其算法的时间复杂度是O(n)。 A.只有表头指针的循环双向链表B.只有表头指针的非循环双向链表 C.只有表尾指针的非循环双向链表 D . 只有表尾指针的循环双向链表 4. 在4个元素的进栈序列给定以后,由这4个元素构成的可能出栈序列共有________种。A.14 B.16 C.17 D.24 5. 在任何一棵二叉树中,如果结点a有左孩子b、右孩子c,则在结点的前序序列、中序序列、后序序列中,_____________。 A.结点b一定在a的前面B.结点a一定在结点c的前面C.结点b一定在结点c的前面D.结点a一定在结点b的前面 6.若二叉树中结点的中序序列是abcdef,则结点的前序序列不可能是_____________。A.dbacef B. acbedfC.efbacd D. bafdce 7. 对稀疏矩阵采用压缩存储,其优点之一是可以_____________。 A.减少非零元素的存储空间B.不减少访问非零元素所需时间 C.减少矩阵的存储空间D.降低非零元素间逻辑关系的复杂程度 8. 设待查找元素关键字的值是47,且已存入变量k中,如果在查找过程中,和k进行比较的关键字值依次是82,72,36,84,47,则所采用的查找方法可能是____________。 A.顺序查找B.分块查找C.折半查找D.平衡二叉排序树查找 9.在线性表中元素很多且各元素逆序排列的情况下,执行_______排序,元素的移动次数最

东北大学历年初试考研真题分享

东北大学96考研题 一、(25分)每小题5分 1.根据下图完成: 1)画出该图的十字链表存储结构图。 2)写出其拓扑排序的输出序列。 3)写出图的强连通分量(支)。 4)写出到的所有路径及简单路径。 2.给定8个权值集合(2,5,3,10,4,7,9,18)画出含有8个叶子结点的最佳三叉 归并树,并计算出 3.知含有8个结点的一棵二叉树,按先序、中序、后序进行遍历后,有些结点序号不清 楚如下图示。要求构造出一棵符合条件的二叉树。 先根序遍历 --- 2 3 --- 5 --- 7 8 中根序遍历 3 --- 4 1 --- 7 8 6 后根序遍历 --- 4 2 --- 6 5 1 4.根据给定的关键字集合(20,15,40,35,45,25,50,30,10)顺序输入 1)构造一棵完全二叉树; 2)画出整理好的一棵堆树; 3)画出一棵输出一个排序记录后的二叉树; 4)画出重新调整好的堆树。 5.下图给出的是一棵三阶B树,处理时每次只能读一个结点到内存。要求: ①计算出由图中结构用计算机查找到关键字(35)的记录并将其删掉,需进行 多少次读/写才能完成? ②画出删除关键字为(35)和关键字为(50)的记录后的三阶B树。

二、(10分)知L1、L2分别为两循环单链表的头结点指针,m,n分别为L1、L2表中数据结点个数。要求设计一算法,用最快速度将两表合并成一个带头结点的循环单链表。 三、(12分)线性表(a1,a2,a3…an)中元素递增有序且按顺序存于计算机内。要求设计一算法完成: (1)用最少的时间在表中查找数值为的元素。 (2)若找到将其与后继元素位置交换。 (3)若找不到将其插入表中并使表中元素仍递增有序。 四、(12分)设给定关键字输入序列为(100,90,120,60,78,35,42,31,15)用散列法散列0——10的地址区间。要求设计一合理的散列函数;冲突时用链表法解决,写出散列算法,并构造出散列表在等概率查找情况下查找成功的平均查找长度是多少? 五、(10分)设为t一棵二叉树的根结点地址指针,试设计一个非递归的算法完成把二叉树中每个结点的左右孩子位置交换。 六、(14分)设L为单链表的头结点地址,其数据结点的数据都是正整数且无相同的,试设计利用直接插入的原则把该链表整理成数据递增的有序单链表的算法。 七、(15分)设t是一棵按后序遍历方式构成的线索二叉树的根结点指针,试设计一个非递归的算法,把一个地址为x的新结点插到t树中,已知地址为y的结点有侧作为结点y的右孩子,并把插入后的二叉树仍为后序线索二叉树。

二叉树的二叉链表表示

====实习报告二“二叉树的二叉链表表示”演示程序 ==== (一)、程序的功能和特点 1. 程序功能:利用链表对非线性二叉树进行存储表示和访问。能够创建二叉树,并且能够按前序遍历显示输出所创建的二叉树。 2. 程序特点:采用java 面向对象语言,对二叉树用二叉链表用类进行封装。能够创建二叉树,并且能够按前序遍历显示输出所创建的二叉树。 (二)、程序的算法设计 算法一:“按前序遍历方式建立二叉树”算法: 1.【逻辑结构与存储结构设计】 逻辑结构:非线性结构。 存储结构:链式存储结构。 头指针bt 头结点指针bt (a) 带头指针的二叉链表 (b) 带头结点的二叉链表 链式 二叉树的二叉链表表示示意图 A ∧ B ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ A C D E D F E F B C G ∧ ∧ G

2.【基本操作设计】 Y N 3.【算法设计】 创建二叉链表文字说明: (1).首先按前序输入二叉树。 (2).判断是否是封闭结点的标识,如果不是则创建二叉链表,递归生成其左右子树。 (3).如果是封闭结点标识则结束; (4).插入成功返回二叉链表的头指针。 4.【高级语言代码】 //按前序遍历方式建立二叉树 public BinTreeNode preOrderCreate ( BinTreeNode p ) { double item=0.0; System.out .println("按照前序遍历次序每次输入一个结点值。"); 开始创建 键盘输入二叉树的二叉链的数据 if ( item != RefValue ) 创建二叉链表结点 封闭叶子 结点 递归生成 左右子树 创建成功返回二叉树的头指创建结束

数据结构练习题--树(题)

第六章树 一.名词解释: 1 树 2。结点的度 3。叶子 4。分支点 5。树的度 6.父结点、子结点 7兄弟 8结点的层数 9树的高度 10 二叉树 11 空二叉树 12 左孩子、右孩子 13孩子数 14 满二叉树 15完全二叉树 16 先根遍历 17 中根遍历 18后根遍历 19二叉树的遍历 20 判定树 21 哈夫曼树 二、填空题 1、树(及一切树形结构)是一种“________”结构。在树上,________结点没有直接前趋。 对树上任一结点X来说,X是它的任一子树的根结点惟一的________。 2、一棵树上的任何结点(不包括根本身)称为根的________。若B是A的子孙,则称A是B 的________ 3、一般的,二叉树有______二叉树、______的二叉树、只有______的二叉树、只有______ 的二叉树、同时有______的二叉树五种基本形态。 4、二叉树第i(i>=1)层上至多有______个结点。 5、深度为k(k>=1)的二叉树至多有______个结点。 6、对任何二叉树,若度为2的节点数为n2,则叶子数n0=______。 7、满二叉树上各层的节点数已达到了二叉树可以容纳的______。满二叉树也是______二叉 树,但反之不然。 8、具有n个结点的完全二叉树的深度为______。 9、如果将一棵有n个结点的完全二叉树按层编号,则对任一编号为i(1<=i<=n)的结点X有: (1)若i=1,则结点X是______;若i〉1,则X的双亲PARENT(X)的编号为______。 (2)若2i>n,则结点X无______且无______;否则,X的左孩子LCHILD(X)的编号为______。 (3)若2i+1>n,则结点X无______;否则,X的右孩子RCHILD(X)的编号为______。 10.二叉树通常有______存储结构和______存储结构两类存储结构。 11.每个二叉链表的访问只能从______结点的指针,该指针具有标识二叉链表的作用。 12.对二叉链表的访问只能从______指针开始,若二叉树为空,则______=NULL. 13.二叉链表中每个存储结点的每个指针域必须有一个值,这个值或者是____________的指针,或者是______。 14.具有n个结点的二叉树中,一共有________个指针域,其中只有________个用来指向结点的左右孩子,其余的________个指针域为NULL。 17.以下程序段采用先根遍历方法求二叉树的叶子数,请在横线处填充适当的语句。 Void countleaf(bitreptr t,int *count)/*根指针为t,假定叶子数count的初值为0*/ {if(t!=NULL) {if((t->lchild==NULL)&&(t->rchild==NULL))________; countleaf(t->lchild,&count); ________ } } 18.一棵二叉树由根、左子树和右子树三部分组成,因此对二叉树的遍历也可相应地分解成________、________、________三项“子任务”。 19.若以D、L、R分别表示二叉树的三项子任务,限定“先左后右”,这样可能的次序有:

设计以先序遍历的顺序建立二叉树的二叉链表存储结构的算法

设计以先序遍历的顺序建立二叉树的二叉链表存储结 构的算法 一、算法简介 二叉树是一种重要的树形结构,它的建立方式有多种,其中一种是按照先序遍历的顺序建立二叉树。这种方式需要将先序遍历序列和二叉树的存储结构相结合,采用二叉链表存储结构。具体流程是按照先序遍历序列的顺序依次创建二叉树的各个节点,同时使用二叉链表结构保存每个节点的数据和指针信息。 二、算法实现 算法的实现主要包括初始化二叉树、创建节点、建立二叉树等步骤,下面对这些步骤进行详细描述。 1. 初始化二叉树 初始化二叉树需要创建一个根节点,同时将根节点的左右指针指向NULL,表示二叉树为空。 2. 创建节点 创建节点需要通过输入元素数据来创建,同时节点的左右指针也需要初始化为NULL。

3. 建立二叉树 建立二叉树是按照先序遍历序列来实现的,具体流程如下: (1)读入当前节点的元素数据,创建节点,并将其作为当前节点。 (2)判断当前节点的元素数据是否为结束符号(这里结束符号可以指定),如果是,则返回NULL。 (3)递归创建当前节点的左子树,将左子树的根节点赋值给当前节点的左指针。 (4)递归创建当前节点的右子树,将右子树的根节点赋值给当前节点的右指针。 (5)返回当前节点。 三、算法优化 虽然上述算法实现简单明了,但它有一个缺点,即无法处理空节点的情况,如果输入的先序遍历序列中存在空节点,那么该算法就无法建立正确的二叉树了。因此,可以在输入的先序遍历序列中使用一个特殊的符号(如#)表示空节点,在建立节点时,如果遇到该符号,则将该节点的指针设置为NULL即可。

四、算法总结 按照先序遍历的顺序建立二叉树是一种基于二叉链表存储结构的建树 方式。它通过递归的方式构建整个二叉树,同时为了处理空节点的情况,还需要对输入的先序遍历序列进行特殊处理。该算法的效率较高,适用于对先序遍历序列已知的情况下建立二叉树。

试写出在链式存储结构上建立一棵二叉树的算法

试写出在链式存储结构上建立一棵二叉树的算法 对于链式存储结构的二叉树,需要定义一个节点结构体来表示每个节点: ```c typedef struct node { int data; struct node *left; struct node *right; } node; ``` 其中,data 表示节点的数据,left 和right 分别表示节点的左子节点和右子节点。接下来,我们可以设计一个函数来创建一棵二叉树,算法步骤如下: 1. 首先创建一个新节点,并让用户输入节点的数据。 2. 如果当前二叉树为空,则将新节点插入到根节点。 3. 否则,从根节点开始遍历二叉树。 4. 如果新节点的数据小于当前节点的数据,则继续遍历左子树。 5. 如果新节点的数据大于当前节点的数据,则继续遍历右子树。 6. 直到找到一个空位置,将新节点插入到该位置。 以下是一个示例代码实现: ```c #include #include typedef struct node { int data; struct node *left; struct node *right; } node; node *create_node(int data) { node *new_node = (node *)malloc(sizeof(node)); new_node->data = data; new_node->left = NULL; new_node->right = NULL; return new_node; } node *insert_node(node *root, int data) { if (root == NULL) {

试写一算法判别给定的二叉树是否为二叉排序树,设此二叉树以二叉链表存储,且树中结点的关键字均不相同

#include #include #define max 10 typedef struct node{ int data; node *lchild,*rchild; }Bitree; Bitree *B[max]; int temp=0; int Btree[max]; Bitree *Creatree(){ //建立二叉树 Bitree *T,*S; int ch; int front,rear,sign; sign=0; front=0; rear=-1; T=NULL; printf("建立二叉树(1表示虚结点,0表示输入结束):\n"); scanf("%d",&ch); while(ch!=0){ if(ch!=1){ //输入结点不是虚结点 S=(Bitree *)malloc(sizeof(Bitree)); S->data=ch; S->lchild=S->rchild=NULL; rear++; B[rear]=S; if(rear==front){ T=S; sign++; } else{ if(sign%2==1) //寻找父结点 B[front]->lchild=S; if(sign%2==0){ B[front]->rchild=S; front++; } sign++; } } else{ //输入结点为虚结点 if(sign%2==0) front++; sign++; } scanf("%d",&ch); } return T; } void Inorder(Bitree *T){ //中序遍历二叉树,并将每个结点数据存入数组中 if(T!=NULL){ Inorder(T->lchild); printf("%d\t",T->data); Btree[temp]=T->data; temp++; Inorder(T->rchild); } } int Judgesort_bitree(int Btree[]){ //判断是否是二叉树 int i,sign=1; for(i=0;iBtree[i+1]){ sign=0; break; } } return sign; } void Judgeout(int a){ //判断输出 if(a==1) printf("给定二叉树是二叉排序树!\n"); if(a==0) printf("给定二叉树不是二叉排序树!\n"); } void main(){ Bitree *T; T=Creatree(); printf("中序遍历:\n"); Inorder(T);

二叉树的二叉链表存储及基本操作

二叉树的二叉链表存储及基本操作 《二叉树的二叉链表存储及基本操作》 一、二叉树的二叉链表表示及存储 1.定义 二叉树的二叉链表存储表示是把一个二叉树存放在计算机中的一种表示形式,它是由一组以结点对象为元素的链表构成的,结点对象中包括数据域和结构域。数据域存放结点的数据元素;结构域由两个指针域组成,其中一个指向左孩子,另一个指向右孩子。 2.存储形式 二叉树的二叉链表存储表示可以用如下的存储形式表示: typedef struct BTNode { TElemType data; // 结点的数据域 struct BTNode *lchild; // 指向左孩子的指针域 struct BTNode *rchild; // 指向右孩子的指针域 } BTNode; // 树结点的定义 typedef BTNode *BiTree; // 定义二叉树的指针类型 3.空的二叉树 把一个指向树结点的指针设为NULL,称为一个空的二叉树。一般在某个树被销毁后,都要把该树设置成空树。 二、二叉树的基本操作 1.求二叉树的结点数 要求二叉树的结点数,可以用递归的方法求解。求n个结点的二

叉树的结点数,可以先求出它的左子树结点数,右子树结点数,再加上根结点的数量就得到了结点数。 // 求二叉树的结点数 int CountBTNode(BiTree T) { if (T == NULL) // 空树,结点数为0 return 0; else // 左子树结点数 + 右子树结点数 + 1 return CountBTNode(T -> lchild) + CountBTNode(T -> rchild) + 1; } 2.求二叉树叶结点数 要求二叉树叶结点数,也可以用递归的方法求解。当一个结点的左子树为空树,右子树也为空树时,它就是一个叶结点,则叶结点数加1;如果结点不是叶结点,则继续求它的左子树叶结点数和右子树叶结点数,再把它们加起来就是该二叉树的叶结点数。 // 求二叉树叶结点数 int CountBTLeaf(BiTree T) { if (T == NULL) // 空树,叶结点数为0 return 0; else if (T -> lchild == NULL && T -> rchild == NULL) //

数据结构实验三——二叉树基本操作及运算实验报告

《数据结构与数据库》 实验报告 实验题目 二叉树的基本操作及运算 一、需要分析 问题描述: 实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目,以及二叉树常用运算。 问题分析: 二叉树树型结构是一类重要的非线性数据结构,对它的熟练掌握是学习数据结构的基本要求。由于二叉树的定义本身就是一种递归定义,所以二叉树的一些基本操作也可采用递归调用的方法。处理本问题,我觉得应该:

1、建立二叉树; 2、通过递归方法来遍历(先序、中序和后序)二叉树; 3、通过队列应用来实现对二叉树的层次遍历; 4、借用递归方法对二叉树进行一些基本操作,如:求叶子数、树的深度宽度等; 5、运用广义表对二叉树进行广义表形式的打印。 算法规定: 输入形式:为了方便操作,规定二叉树的元素类型都为字符型,允许各种字符类型的输入,没有元素的结点以空格输入表示,并且本实验是以先序顺序输入的。 输出形式:通过先序、中序和后序遍历的方法对树的各字符型元素进行遍历打印,再以广义表形式进行打印。对二叉树的一些运算结果以整型输出。 程序功能:实现对二叉树的先序、中序和后序遍历,层次遍历。计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目。对二叉树的某个元素进行查找,对二叉树的某个结点进行删除。 测试数据:输入一:ABC□□DE□G□□F□□□(以□表示空格),查找5,删除E 预测结果:先序遍历ABCDEGF 中序遍历CBEGDFA 后序遍历CGEFDBA 层次遍历ABCDEFG 广义表打印A(B(C,D(E(,G),F))) 叶子数3 深度5 宽度2 非空子孙数6 度为2的数目2 度为1的数目2 查找5,成功,查找的元素为E 删除E后,以广义表形式打印A(B(C,D(,F))) 输入二:ABD□□EH□□□CF□G□□□(以□表示空格),查找10,删除B 预测结果:先序遍历ABDEHCFG 中序遍历DBHEAGFC 后序遍历DHEBGFCA 层次遍历ABCDEFHG 广义表打印A(B(D,E(H)),C(F(,G))) 叶子数3 深度4 宽度3 非空子孙数7 度为2的数目2 度为1的数目3 查找10,失败。

数据结构 第6章习题

习题 1.对于如图6-21所示的二叉树,试给出: (1)它的顺序存储结构示意图。 (2)它的二叉链表存储结构示意图。 (3)它的三叉链表存储结构示意图。 图6-21 题1图 2.证明:在结点数多于1的哈夫曼树中不存在度为1的结点。 3.证明:若哈夫曼树中有n个叶结点,则树中共有2n-1个结点。 4.证明:由二叉树的前序序列和中序序列可以唯一地确定一棵二叉树。 5.已知一棵度为m的树中有n1个度为1的结点,n2个度为2的结点,……,n m个度为m 的结点,问该树中共有多少个叶子结点?有多少个非终端结点? 6.设高度为h的二叉树上只有度为0和度为2的结点,问该二叉树的结点数可能达到的最大值和最小值。 7.求表达式(a+b*(c-d))-e/f的波兰式(前缀式)和逆波兰式(后缀式)。 8.画出和下列已知序列对应的二叉树。 (1)二叉树的先序次序访问序列为:GFKDAIEBCHJ。 (2)二叉树的中序访问次序为:DIAEKFCJHBG。 9.画出和下列已知序列对应的二叉树。 (1)二叉树的后序次序访问序列为:CFEGDBJLKIHA。 (2)二叉树的中序访问次序为:CBEFDGAJIKLH。 10.画出和下列已知序列对应的二叉树。 (1)二叉树的层次序列为:ABCDEFGHIJ。 (2)二叉树的中序次序为:DBGEHJACIF。 11.给定一棵用二叉链表表示的二叉树,其根指针为root。试写出求二叉树结点的数目的算法(递归算法或非递归算法)。 12.设计一个算法,要求该算法把二叉树的叶结点按从左至右的顺序链成一个单链表。二叉树按二叉链表方式存储,链接时用叶结点的rchild域存放链指针。 13.给定一棵用二叉链表表示的二叉树,其根指针为root。试写出求二叉树的深度的算法。14.给定一棵用二叉链表表示的二叉树,其根指针为root。试写出求二叉树各结点的层数的算法。 15.给定一棵用二叉链表表示的二叉树,其根指针为root。试写出将二叉树中所有结点的左、右子树相互交换的算法。 16.一棵n个结点的完全二叉树以一维数组作为存储结构,试设计非递归算法对该完全二叉树进行前序遍历。

构建二叉树的二叉链表存储结构

二叉树的二叉链表存储结构构建方法假设有关二叉树的二叉链表存储的类型定义如下: typedef struct BiTNode{ // 结点结构 ElemType data ;//数据域 struct BiTNode *Lchild ;//左孩子指针 struct BiTNode *Rchild;//右孩子指针 } BiTNode ,*BiTree ; 1 利用扩展二叉树的先序序列构建 只根据二叉树的先序序列是不能唯一确定一棵二叉树的。针对这一问题,可做如下处理:对二叉树中每个结点的空指针引出一个虚结点,设其值为#,表示为空,把这样处理后的二叉树称为原二叉树的扩展二叉树。扩展二叉树的先序序列可唯一确定这棵二叉树。如图 1 所示,给出了一棵二叉树的扩展二叉树,以及该扩展二叉树的先序序列。 建立二叉链表的算法如下: void Create(BiTree &T) {//输入扩展二叉树的先序序列,构建二叉链表scanf(&ch); //输入一个元素 if (ch=='# ') T = NULL; else { T= (BiTree)malloc(sizeof(BiTNode)); //申请根结点 T->data =ch; // 给根结点数据域赋值 Create(T->Lchild);//建左子树 Create(T->Rchild);//建右子树 } } // Create 2 利用二叉树的先序序列和中序序列 容易证明:由一棵二叉树的先序序列和中序序列可唯一的确定一棵二叉树。 基本思想:先根据先序序列的第一个元素建立根结点;然后在中序序列中找到该元素,确定根结点的左、右子树的中序序列;根据左、右子树的中序序列确定左、右子树中结点的个数;再根据结点个数在先序序列中确定左、右子树的先序序列;最后由左子树的先序序列与中序序列建立左子树,由右子树的先序序列与中序序列建立右子树。 显然,这是一个递归过程。假设先序序列放在数组pre[0..n-1]中,中序序列放在数组mid[0..n-1]中,n是二叉树中元素的个数,其算法如下: int Find(ElemType *P, int L2 ,int H2, ElemType x) {//在数组P的区间L2..H2内确定x的位置 i=L2; while(P[i]!=x) i++; return i; }// Find void Create (BiTree &T, int L1, int H1, int L2, int H2) {//已知先序序列pre[L1..H1], //中序序列mid[L2..H2]构建二叉链表 if (L2>H2) T=NULL; //建空树 else { T =(BiTree)malloc(sizeof(BiTNode)); //创建根结点T T ->data=pre[L1]; //给根数据域赋值 k=Find(mid, L2, H2, pre[L1]); //找根在中序序列的位置 Create (T ->Lchild, L1+1,k+L1-L2, L2,k-1); //创建左子树 Create(T->Rchild,k+L1-L2+1,H1,k+1, H2); //创建右子树 } }// Create 3 利用扩展完全二叉树的顺序存储 约定对二叉树上的结点从根结点起,自上而下,自左而右进行连续编号,根结点的编号为1。深度为k的,有n个结点的二叉树,当且仅当其每个结点的编号都与深度为k的满二叉树中编号为1至n中的结点一一对应时,称其为完全二叉树。 如果一棵二叉树不是完全二叉树,可以用添加虚结点的方式将其扩展为一棵完全二叉树,虚结点的值设为# ,表示该结点不存在,把这样处

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

实验四二叉树的基本操作 一、实验目的: (1)掌握二叉树的定义和存储表示,学会建立一棵特定二叉树的方法; (2)掌握二叉树的遍历算法(先序、中序、后序遍历算法)的思想; (3)掌握二叉树和叶子数、深度之间的关系及联系。 二、实验内容: 构造二叉树,再实现二叉树的先序、中序、后序遍历,最后统计二叉树的叶子数和深度。 三、实验步骤: (一)需求分析 1. 二叉树的建立首先要建立一个二叉链表的结构体,包含根节点和左右子树.因为树的每一个左右子树又是一颗二叉树,所以用递归的方法来建立其左右子树。二叉树的遍历是一种把二叉树的每一个节点访问并输出的过程,遍历时根结点与左右孩子的输出顺序构成了不同的遍历方法,这个过程需要按照不同的遍历的方法,先输出根结点还是先输出左右孩子,可以用选择语句来实现。 2.程序的执行命令为: 1)构造结点类型,然后创建二叉树。 2)根据提示,从键盘输入各个结点。 3)通过选择一种方式(先序、中序或者后序)遍历. 4)输出结果,结束。 (二)概要设计 1。二叉树的二叉链表结点存储类型定义 typedefstruct Node { DataType data;

struct Node *LChild; struct Node *RChild; }BitNode,*BitTree; 2。建立如下图所示二叉树: 3。本程序包含六个模块 1) 主程序模块 2)先序遍历模块 3)中序遍历模块 4)后序遍历模块 5)叶子数模块 6)深度模块

四、测试结果 1. 进入演示程序后的显示主界面: 请输入二叉树中的元素; 先序、中序、后序遍历和叶子数、深度分别输出结果。 2.测试结果 以扩展先序遍历序列输入,其中#代表空子树:ABC##DE#G##F### 先序遍历序列为:ABCDEGF 中序遍历序列为:CBEGDFA 后序遍历序列为:CGEFDBA 此二叉树的叶子数为:3 此二叉树的深度为:5 3。程序运行结果截图:

数据结构实验二叉树

实验六:二叉树及其应用 一、实验目的 树是数据结构中应用极为广泛的非线性结构,本单元的实验达到熟悉二叉树的存储结构的特性,以及如何应用树结构解决具体问题。 二、问题描述 首先,掌握二叉树的各种存储结构和熟悉对二叉树的基本操作。其次,以二叉树表示算术表达式的基础上,设计一个十进制的四则运算的计算器。 如算术表达式: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 运算,并将其结果再次放入栈中,此时表达式结束,则栈中的元素值就是该表达式最后的运算结果。当然将原始的中缀表达式转换为后缀表达式比较关键,要同时考虑操作符的优先级以及对有括号的情况下的处理,相关内容会在算法具体实现中详细讨论。 2、求值过程

数据结构课程设计报告——二叉排序树(用顺序表结构存储)

摘要: 数据结构是研究与数据之间的关系,我们称这一关系为数据的逻辑结构,简称数据结构。当数据的逻辑结构确定以后,数据在物理空间中的存储方式,称为数据的存储结构。相同的逻辑结构可以具有不同的存储结构,因而有不同的算法。本次课程设计,程序中的数据采用“树形结构”作为其数据结构。而二叉搜索树又是一种特殊的二叉树。本课程设中的二叉排序树是基于二叉链表作存储结构的,一共要实现五项基本的功能。它们分别是二叉搜索树的创建、中序遍历、查找结点、删除结点和计算二叉排序树搜索成功时的平均查找长度。 关键词:二叉排序树;中序遍历;搜索结点;删除结点;平均查找长度

目录 1需求分析 (1) 1.1课程设计题目、任务及要求 (1) 1.2课程设计思想 (1) 2概要设计 (2) 2.1 二叉排序树的定义 (2) 2.2二叉链表的存储结构 (2) 2.3建立二叉排序树 (2) 2.4二叉排序树的生成过程 (3) 2.5中序遍历二叉树 (3) 2.6二叉排序树的查找 (3) 2.7二叉排序树的插入 (4) 2.8平均查找长度 (4) 3详细设计和实现 (4) 3.1主要功能模块设计 (4) 3.2主程序设计 (5) 4调试与操作说明 (12) 4.1程序调试 (12) 4.2程序操作说明 (13) 总结 (16) 致谢 (17) 参考文献 (18)

1需求分析 1.1课程设计题目、任务及要求 二叉排序树。用二叉链表作存储结构 (1)以(0)为输入结束标志,输入数列L,生成一棵二叉排序树T; (2)对二叉排序树T作中序遍历,输出结果; (3)计算二叉排序树T查找成功的平均查找长度,输出结果; (4)输入元素x,查找二叉排序树T:若存在含x的结点,则删除该结点,并作中序 遍历(执行操作2);否则输出信息“无x”; 1.2课程设计思想 建立二叉排序树采用边查找边插入的方式。查找函数采用递归的方式进行查找。如果查找成功则不应再插入原树,否则返回当前结点的上一个结点。然后利用插入函数将该元素插入原树。 对二叉排序树进行中序遍历采用递归函数的方式。在根结点不为空的情况下,先访问左子树,再访问根结点,最后访问右子树。由于二叉排序树自身的性质,左子树小于根结点,而根结点小于右子树,所以中序遍历的结果是递增的。 计算二插排序树的平均查找长度时,仍采用类似中序遍历的递归方式,用s记录总查找长度,j记录每个结点的查找长度,s置初值为0,采用累加的方式最终得到总查找长度s。平均查找长度就等于s/i(i为树中结点的总个数)。 删除结点函数,采用边查找边删除的方式。如果没有查找到,则不对树做任何的修改;如果查找到结点,则分四种情况分别进行讨论: 1、该结点左右子树均为空; 2、该结点仅左子树为空; 3、该结点仅右子树为空; 4、该结点左右子树均不为空。

java leetcode构建node二叉树方法

java leetcode构建node二叉树方法Constructing a node binary tree in Java for a LeetCode problem can be a challenging yet rewarding experience. Node binary trees are a fundamental data structure in computer science and are commonly used in various algorithms and applications. By understanding how to build and manipulate a node binary tree in Java, you can improve your problem-solving skills and become a more proficient programmer. 在Java中为LeetCode问题构建一个节点二叉树可能是一个具有挑战性但有益的体验。节点二叉树是计算机科学中的一种基本数据结构,通常在各种算法和应用中使用。通过了解如何在Java中构建和操作节点二叉树,您可以提高解决问题的能力,并成为更熟练的程序员。 To construct a node binary tree in Java, you first need to define a Node class that represents the structure of a single node in the tree. This class typically contains fields for the data stored in the node, as well as references to the left and right children of the node. By encapsulating this information in a Node class, you can easily create and manipulate nodes within the binary tree.

bjfuoj基于二叉链表的二叉树高度的计算

bjfuoj基于二叉链表的二叉树高度的计算 1. 简介 二叉树是一种常见的数据结构,它具有丰富的应用场景,如在编程中用于构建高效的搜索算法、表达数学表达式以及构建文件系统等。而对于二叉树的操作,其中一个重要的操作就是计算二叉树的高度。在本文中,我们将重点讨论基于二叉链表的二叉树高度的计算问题,并对此进行详细阐述。 2. 二叉链表的定义 在计算二叉树的高度之前,我们首先需要了解二叉链表的定义。二叉链表是一种用于表示二叉树的链式存储结构。在二叉链表中,每个节点包含数据域以及左右子树指针域,通过指针的方式将不同的节点连接起来,从而构成了一棵二叉树。以下是二叉链表的节点定义: ```C++ struct BiTNode { int data; struct BiTNode *lchild, *rchild; // 左右孩子指针 }; ``` 利用上述节点定义,我们可以便捷地构建一个二叉树,并通过指针将

各个节点相连,形成一棵完整的二叉树。 3. 二叉树高度的定义 在计算二叉树的高度之前,我们需要明确二叉树高度的定义。二叉树 的高度是指从根节点到叶子节点的最长路径的边数。二叉树的高度即 为从根节点到最远叶子节点的路径长度。二叉树的高度反映了二叉树 的层数和结构的复杂程度,是对二叉树结构的重要描述。 4. 二叉树高度的计算方法 基于二叉链表的二叉树高度的计算可以采用递归和非递归两种方法。 4.1 递归方法 递归方法是最常用的计算二叉树高度的方法之一。其基本思想是利用 递归的方式,分别计算二叉树的左子树和右子树的高度,然后取其中 较大的一个加上1即可得到整棵二叉树的高度。具体的递归代码如下: ```C++ int getHeight(BiTNode *root) { if (root == nullptr) { return 0; } int leftHeight = getHeight(root->lchild); int rightHeight = getHeight(root->rchild);

相关主题
文本预览
相关文档 最新文档