二叉树排序算法
![二叉树排序算法](https://img.360docs.net/img37/01nx42sgp0tad4jg91q2-71.webp)
![二叉树排序算法](https://img.360docs.net/img37/01nx42sgp0tad4jg91q2-72.webp)
实验报告
课程名称:数据结构实验课程
实验四、串的基本操作练习
一、实验目的
1. 掌握二叉树的存储实现
2. 掌握二叉树的遍历思想
3. 掌握二叉树的常见算法的程序实现
二、实验环境
VC++6.0
三、实验内容
1.输入字符序列,建立二叉树的二叉链表结构。(可以采用先序序列)
2.实现二叉树的先序、中序、后序的递归遍历算法。
3.实现二叉树的先序、中序、后序的非递归遍历算法。
4.求二叉树的高度。
5.求二叉树的结点个数。
6.求二叉树的叶子结点的个数。
四、实验要求:
分别编写实现上述算法的子函数,并编写一个主函数,在主函数中设计一个简单的菜单,分别调用上述子函数。
五、实验步骤和结果
1.打开vc,新建文本,命名二叉树算法,编写代码。
2.编写代码:
#include
#include
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
int i=0;
/*--------------------------------------建立堆栈------------------------------------------*/
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
} BiTNode,*BiTree;//树类型
typedef struct SqStack
{
BiTNode *base;
BiTNode *top;
int stacksize;
} SqStack;//栈类型
void InitStack(SqStack *S)//创建二叉树
{
S->base=(BiTNode*)malloc(STACK_INIT_SIZE*sizeof(BiTNode));
S->top=S->base;
S->stacksize=STACK_INIT_SIZE;
}
void Push(SqStack *S,BiTNode e)//进栈
{
if(S->top - S->base >= S->stacksize)//如果栈空间不足
{
S->base=(BiTNode*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(B iTNode));
S->top=S->base+S->stacksize;
S->stacksize+=STACKINCREMENT;
}
*(S->top)=e;
S->top++;
}
BiTNode Pop(SqStack *S)//出栈
{
S->top --;
return *S->top;
}
int StackEmpty(SqStack *S)//判断栈是否非空
{
if(S->top == S->base )
return 1;
else
return 0;
}
/*---------------------------------------------递归部分-------------------------------------------*/
BiTree Create(BiTree T)//建立二叉树
{
char ch;
ch=getchar();
if(ch=='#')
T=NULL;
else
{
if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))
printf("申请内存空间失败!");
T->data=ch;
T->lchild=Create(T->lchild);
T->rchild=Create(T->rchild);
}
return T;
}
int Sumleaf(BiTree T)//计算叶子节点
{
int sum=0,m,n;
if(T)
{
if((!T->lchild)&&(!T->rchild))
sum++;
m=Sumleaf(T->lchild);
sum+=m;
n=Sumleaf(T->rchild);
sum+=n;
}
return sum;
}
/*int Sumleaf(BiTree T)//老师课堂上的计算叶子数的代码,没有问题{
if(!(T->lchild&&T->rchild))
return 1;
else
return(Sumleaf(T->lchild)+Sumleaf(T->rchild));
}*/
int PreOrder_1(BiTree T)//先序递归
{
if(T)
{
printf("%c",T->data);//根节点
i++;
PreOrder_1(T->lchild);
PreOrder_1(T->rchild);
}
return i;
}
void InOrder_1(BiTree T)//中序递归
{
if(T)
{
InOrder_1(T->lchild);
printf("%c",T->data);//根节点
InOrder_1(T->rchild);
}
}
void PostOrder_1(BiTree T)//后序递归
{
if(T)
{
PostOrder_1(T->lchild);
PostOrder_1(T->rchild);
printf("%c",T->data);//根节点
}
}
int Depth(BiTree T)//计算高度
{
int dep=0,depl,depr;
if(!T)
dep=0;
else
{
depl=Depth(T->lchild);
depr=Depth(T->rchild);
dep=1+(depl>depr?depl:depr);
}
return dep;
}
/*-------------------------------------非递归部分----------------------------------------*/
{
SqStack S;
BiTree p=T,q;
q=(BiTNode *)malloc(sizeof(BiTNode));
InitStack(&S);
if(p)
Push(&S,*p);
while(!StackEmpty(&S))
{
p=q;
*p=Pop(&S);//移到叶子时,出栈,输出出栈元素
printf("%c",p->data);
if(p->rchild)//如果有右孩子,访问右孩子,并沿右孩子移位Push(&S,*p->rchild);
if(p->lchild)//如果没有右孩子,访问左孩子,并移到左孩子Push(&S,*p->lchild);
}
}
void InOrder_2(BiTree T)//中序非递归
{
SqStack S;
BiTree p,q;
p=T;
InitStack(&S);
q=(BiTNode *)malloc(sizeof(BiTNode));
while(p||!StackEmpty(&S))
{
if(p)
{
Push(&S,*p);
p=p->lchild;
}
else
{
p=q;
*p=Pop(&S);
printf("%c",p->data);
p=p->rchild;
}
}
}
{
int mark[100];//标示
int t=0;
int top=-1;//下标
SqStack S;
BiTree p=T,q;
InitStack(&S);
q=(BiTNode *)malloc(sizeof(BiTNode));
if(p&&(p->lchild||p->rchild))
{
do
{
while((p->lchild||p->rchild)&&mark[top+1]!=2)//循环直到让p向左滑到叶子节点
{
top++;
Push(&S,*p);//每循环一次,当前结点入栈
mark[top]=1;//结点第一次入栈时,标志为1
if(p->lchild)
p=p->lchild;//找最左子树
else
if(p->rchild)
p=p->rchild;
}
if(p)
printf("%c",p->data);
p=q;
*p=Pop(&S);
top--;//出栈,下标归位
if(!p->rchild||!p->lchild)//防止出现不必要的再次入栈
mark[top+1]=2;
if(mark[top+1]==1&&p->rchild)//若结点是第一次出栈,则再入栈
{
top++;
Push(&S,*p);
mark[top]=2;//结点第二次入栈时,标志为2
p=p->rchild;//访问右子树
mark[top+1]=0;
}
if(mark[0]==2&&t==0)//当栈剩下最后一个结点的时候,把下标初始化。
{
int i;
t++;
for(i=0;i<100;i++)
{
mark[i]=0;
}
}
}while (top!=-1&&!StackEmpty(&S)&&p);
printf("%c",p->data);//输出根节点
}
else
if(p)
printf("%c",p->data);//当树仅有一个结点时
}
void main()
{
BiTree Ta;
int sum,dep,total;
printf("输入数据创建二叉树");
Ta=Create(Ta);
printf("************************递归遍历***************************");
printf("\n递归先序遍历:\n");
total=PreOrder_1(Ta);
printf("\n递归中序遍历:\n");
InOrder_1(Ta);
printf("\n递归后序遍历:\n");
PostOrder_1(Ta);
sum=Sumleaf(Ta);
printf("\n");
printf("*******************结点总数叶子数和高度********************");
printf("\n该二叉树结点总数为:%d",total);
printf("\n叶子总数为:%d",sum);
dep=Depth(Ta);
printf("\n高度为:%d\n",dep);
printf("***********************非递归遍历**************************");
printf("\n非递归先序遍历:\n");
PreOrder_2(Ta);
printf("\n非递归中序遍历:\n");
InOrder_2(Ta);
printf("\n非递归后序遍历:\n");
PostOrder_2(Ta);
printf("\n\n");
}
六、实验结果和讨论
1.首先,代码,修改语法错误,调试。运行
2.按要求输入二叉树abc##de#g##f###
3.运行结果符合要求,再次输入一颗二叉树。-+a##*b##-c##d##/e##f##
4.运算结果合格,再次输入。abcd##e##fg##h##ijl##m##kn##o##
5.运行结果正确。下面输入特殊的树,进行健壮性检查,比如输入空树,#
6.空树没有结点叶子,结点总数和高度都为0,其他的运算均不输出任何东西
再输入仅有一个结点的树a##。
七、总结
1.通过本实验了解了二叉树的遍历算法,复习了递归,堆栈的使用。
2.程序运算复杂,代码长度大,调试困难,漏洞多,尤其是后序非递归的遍历,用到了二次进栈,并对进栈的次数进行标记,中间会有很多比较特殊的二叉树会使程序无法完全访问到二叉树的各个结点,造成逻辑错误,做了多次的修改,
完善,以上输入了几种有代表性的树,都是本来不能运行成功,修改后正常运行的结果。
3.遇到一个难题,就是不知道如何提示用户输入的字符是否能构成一棵完整的二叉树。
4.代码很长,可能对一些较为特殊的二叉树的处理会出错,目前试过好几种有代表性的树,均未发现问题。考虑到时间问题,没作深入的探讨。
二叉树的各种算法
二叉树的各种算法.txt男人的承诺就像80岁老太太的牙齿,很少有真的。你嗜烟成性的时候,只有三种人会高兴,医生你的仇人和卖香烟的。 /*用函数实现如下二叉排序树算法: (1)插入新结点 (2)前序、中序、后序遍历二叉树 (3)中序遍历的非递归算法 (4)层次遍历二叉树 (5)在二叉树中查找给定关键字(函数返回值为成功1,失败0) (6)交换各结点的左右子树 (7)求二叉树的深度 (8)叶子结点数 Input 第一行:准备建树的结点个数n 第二行:输入n个整数,用空格分隔 第三行:输入待查找的关键字 第四行:输入待查找的关键字 第五行:输入待插入的关键字 Output 第一行:二叉树的先序遍历序列 第二行:二叉树的中序遍历序列 第三行:二叉树的后序遍历序列 第四行:查找结果 第五行:查找结果 第六行~第八行:插入新结点后的二叉树的先、中、序遍历序列 第九行:插入新结点后的二叉树的中序遍历序列(非递归算法) 第十行:插入新结点后的二叉树的层次遍历序列 第十一行~第十三行:第一次交换各结点的左右子树后的先、中、后序遍历序列 第十四行~第十六行:第二次交换各结点的左右子树后的先、中、后序遍历序列 第十七行:二叉树的深度 第十八行:叶子结点数 */ #include "stdio.h" #include "malloc.h" #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0
#define INFEASIBLE -1 #define OVERFLOW -2 typedef int Status; typedef int KeyType; #define STACK_INIT_SIZE 100 // 存储空间初始分配量 #define STACKINCREMENT 10 // 存储空间分配增量 #define MAXQSIZE 100 typedef int ElemType; typedef struct BiTNode{ ElemType data; struct BiTNode *lchild,*rchild;//左右孩子指针 } BiTNode,*BiTree; Status SearchBST(BiTree T,KeyType key,BiTree f,BiTree &p) { if(!T){p=f;return FALSE;} else if(key==T->data){p=T;return TRUE;} else if(key
二叉排序树的建立及遍历的实现
课程设计任务书 题目: 二叉排序树的建立及遍历的实现 初始条件: 理论:学习了《数据结构》课程,掌握了基本的数据结构和常用的算法; 实践:计算机技术系实验室提供计算机及软件开发环境。 要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1、系统应具备的功能: (1)建立二叉排序树; (2)中序遍历二叉排序树并输出排序结果; 2、数据结构设计; 3、主要算法设计; 4、编程及上机实现; 5、撰写课程设计报告,包括: (1)设计题目; (2)摘要和关键字; (3)正文,包括引言、需求分析、数据结构设计、算法设计、程序实现及测试、设计体会等; (4)结束语; (5)参考文献。 时间安排:2007年7月2日-7日(第18周) 7月2日查阅资料 7月3日系统设计,数据结构设计,算法设计 7月4日-5日编程并上机调试7月6日撰写报告 7月7日验收程序,提交设计报告书。 指导教师签名: 2007年7月2日 系主任(或责任教师)签名: 2007年7月2日 排序二叉树的建立及其遍历的实现
摘要:我所设计的课题为排序二叉树的建立及其遍历的实现,它的主要功能是将输入的数据 组合成排序二叉树,并进行,先序,中序和后序遍历。设计该课题采用了C语言程序设计,简洁而方便,它主要运用了建立函数,调用函数,建立递归函数等等方面来进行设计。 关键字:排序二叉树,先序遍历,中序遍历,后序遍历 0.引言 我所设计的题目为排序二叉树的建立及其遍历的实现。排序二叉树或是一棵空树;或是具有以下性质的二叉树:(1)若它的左子树不空,则作子树上所有的结点的值均小于它的根结点的值;(2)若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;(3)它的左,右子树也分别为二叉排序树。对排序二叉树的建立需知道其定义及其通过插入结点来建立排序二叉树,遍历及其输出结果。 该设计根据输入的数据进行建立排序二叉树。对排序二叉树的遍历,其关键是运用递归 调用,这将极大的方便算法设计。 1.需求分析 建立排序二叉树,主要是需要建立节点用来存储输入的数据,需要建立函数用来创造排序二叉树,在函数内,需要进行数据比较决定数据放在左子树还是右子树。在遍历二叉树中,需要建立递归函数进行遍历。 该题目包含两方面的内容,一为排序二叉树的建立;二为排序二叉树的遍历,包括先序遍历,中序遍历和后序遍历。排序二叉树的建立主要运用了循环语句和递归语句进行,对遍历算法运用了递归语句来进行。 2.数据结构设计 本题目主要会用到建立结点,构造指针变量,插入结点函数和建立排序二叉树函数,求深度函数,以及先序遍历函数,中序遍历函数和后序遍历函数,还有一些常用的输入输出语句。对建立的函明确其作用,先理清函数内部的程序以及算法在将其应用到整个程序中,在建立排序二叉树时,主要用到建立节点函数,建立树函数,深度函数,在遍历树是,用到先序遍历函数,中序遍历函数和后序遍历函数。
二叉树排序算法
实验报告 课程名称:数据结构实验课程 实验四、串的基本操作练习 一、实验目的 1. 掌握二叉树的存储实现 2. 掌握二叉树的遍历思想 3. 掌握二叉树的常见算法的程序实现 二、实验环境 VC++6.0 三、实验内容 1.输入字符序列,建立二叉树的二叉链表结构。(可以采用先序序列) 2.实现二叉树的先序、中序、后序的递归遍历算法。 3.实现二叉树的先序、中序、后序的非递归遍历算法。 4.求二叉树的高度。 5.求二叉树的结点个数。 6.求二叉树的叶子结点的个数。 四、实验要求: 分别编写实现上述算法的子函数,并编写一个主函数,在主函数中设计一个简单的菜单,分别调用上述子函数。 五、实验步骤和结果 1.打开vc,新建文本,命名二叉树算法,编写代码。 2.编写代码: #include
BiTNode *base; BiTNode *top; int stacksize; } SqStack;//栈类型 void InitStack(SqStack *S)//创建二叉树 { S->base=(BiTNode*)malloc(STACK_INIT_SIZE*sizeof(BiTNode)); S->top=S->base; S->stacksize=STACK_INIT_SIZE; } void Push(SqStack *S,BiTNode e)//进栈 { if(S->top - S->base >= S->stacksize)//如果栈空间不足 { S->base=(BiTNode*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(B iTNode)); S->top=S->base+S->stacksize; S->stacksize+=STACKINCREMENT; } *(S->top)=e; S->top++; } BiTNode Pop(SqStack *S)//出栈 { S->top --; return *S->top; } int StackEmpty(SqStack *S)//判断栈是否非空 { if(S->top == S->base ) return 1; else return 0; } /*---------------------------------------------递归部分-------------------------------------------*/
二叉树的基本 操作
//二叉树的基本操作 #include [1996] 设t 为一棵二叉树的根结点地址指针,试设计一个非递归算法完成把二叉树中每个结点的左右孩子位置交换。 int swithLRChild(BiTree *t) { BiTree *stack[100] = {0}; int stack_length = 0; if (NULL == t){ return 0; } stack[stack_length++] = t; while (stack_length > 0){ //pop stack BiTree *node = stack[stack_length - 1]; stack_length -= 1; BiTree *temp = node ->lchild; node->lchild = node ->rchild; node->rchild = temp; if (NULL != node ->rchild){ stack[stack_length++] = node ->rchild;} if (NULL != node ->lchild){ stack[stack_length++] = node ->lchild; } } return 1; } [1998]一棵高度为K 且有n个结点的二叉排序树,同时又是一棵完全二叉树存于向量t 中,试设计删除树中序号为i 且具有左右孩子的一个结点,而不使存储量增加保证仍为二叉排序树(不一定是完全二叉树)的算法。 //存数据的位置是从 1 的索引开始的,避免需要访问索引为0 的空间,避免需要频繁的索引 转换 void delNodeInSortedBiTree(int *sorted_bitree, int *last_index,int i) { //因为题目中描述具有左右孩子,所以直接从左孩子的最右边叶子节点开始//分两种情况,左孩子没有右孩子,那么左孩子之后的节点都移动一个位子//左孩子存在右孩子,则从右孩子的左孩子一直走,到叶子节点停止,因为是叶子节点//就不需要移动元素了 int del_node_index = 2*i; if (2*del_node_index + 1 >= *last_index) 二叉树遍历算法的实现 题目:编制二叉树遍历算法的实现的程序 一.需求分析 1.本演示程序中,二叉树的数据元素定义为非负的整型(unsigned int)数据,输 入-1表示该处没有节点 2.本演示程序输入二叉树数据均是按先序顺序依次输入 3.演示程序以用户和计算机对话方式执行,即在计算机终端上显示“提示信息” 之后,由用户在键盘上输入演示程序中规定的运算命令;相应的输入数据和运 算结果显示在其后 4.本实验一共包括三个主要程序,分别是:1)二叉树前序,中序,后序遍历递归 算法实现2)二叉树前序中序遍历非递归算法实现3)二叉树层次遍历算法实现 5.本程序执行命令包括:1)构建二叉树2)二叉树前序递归遍历3)二叉树中序 递归遍历4)二叉树后序递归遍历5)二叉树前序非递归遍历6)二叉树中序非 递归遍历7)二叉树层次遍历 6.测试数据 (1)7 8 -1 9 10 -1 -1 -1 6 11 -1 -1 12 13 -1 -1 14 -1 -1 (2)1 -1 -1 (3)7 8 -1 -1 9 -1 -1 二.概要设计 1.为实现二叉树的遍历算法,我们首先给出如下抽象数据类型 1)二叉树的抽象数据类型 ADT BiTree{ 数据对象D:D是具有相同特性的数据元素的集合 数据关系R: 若D=Φ,则R=Φ,称BiTree是空二叉树; 若D≠Φ,则R={H},H是如下二元关系: (1)在D中存在唯一的成为根的数据元素root,它在关系H下无前驱; (2)若D-{H}≠Φ,则存在D-{root}={D1,D r},且D1∩D r=Φ (3)若D1≠Φ,则D1中存在唯一的元素x1, 实验三二叉树的基本运算 一、实验目的 1、使学生熟练掌握二叉树的逻辑结构和存储结构。 2、熟练掌握二叉树的各种遍历算法。 二、实验内容 题目一:二叉树的基本操作实现(必做题) [问题描述] 建立一棵二叉树,试编程实现二叉树的如下基本操作: 1. 按先序序列构造一棵二叉链表表示的二叉树T; 2. 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列; 3. 求二叉树的深度/结点数目/叶结点数目;(选做) 4. 将二叉树每个结点的左右子树交换位置。(选做) [基本要求] 从键盘接受输入(先序),以二叉链表作为存储结构,建立二叉树(以先序来建立), [测试数据] 如输入:ABCффDEфGффFффф(其中ф表示空格字符) 则输出结果为 先序:ABCDEGF 中序:CBEGDFA 后序:CGEFDBA 层序:ABCDEFG [选作内容] 采用非递归算法实现二叉树遍历。 三、算法设计 1、主要思想:根据二叉树的图形结构创建出二叉树的数据结构,然后 用指针对树进行操作,重点掌握二叉树的结构和性质。 2、本程序包含四个模块: (1)结构体定义 (2)创建二叉树 (3)对树的几个操作 (4)主函数 四、调试分析 这是一个比较简单程序,调试过程中并没有出现什么问题,思路比较清晰 五、实验结果 六、总结 此次上机实验对二叉树进行了以一次实际操作,让我对二叉树有了更深的了解,对二叉树的特性有了更熟悉的认知,让我知 道了二叉树的重要性和便利性,这对以后的编程有更好的帮助。 七、源程序 #include 二叉树删除算法 姓名:李晓娜学号:20122593 班级:软件一班 1、问题描述 使用算法实现二叉树的建立及删除。 2、解题思路 二叉树的删除操作比较复杂,主要分三种情况:1、删除没有子节点的节点,2、删除只有一个节点的节点(其中有分为两种情况),3、删除有两个节点的节点。 首先看第一种情况:(删除没有子节点的节点) 删除没有子节点的节点只需要将被删除节点的父节点指向空即可 第二种情况:(删除只有一个子节点的节点) 删除有一个子节点的节点,只需要将被删除节点的父节点指向删除节点的子节点即可 第三种情况:(删除有两个子节点的节点,即左右子树都非空) 删除有两个子节点的节点,到底谁来替代被删除的节点的位置呢?是左节点,还是右节点,代替以后这个子节点的子节点应该怎么安排?一系列的问题都出来了。。。简便的方法就是要找一个节点代替这个被删除的节点,这就要从二叉搜索树的定义来看。因为二叉搜索树是有序的,我们要找的节点在这棵树上,而且这个节点要比被删除的左节点大,比右节点小。先看看这个已被删除节点的右节点为根的子树的所有节点的值都要比被删除节点大,这是二叉搜索树定义的,但是要在这个集合中找到最小的一个,来代替被删除的节点,那就要在这棵子树上一直往左找。这个节点比被删除的节点的右节点小,且比左节点大,那这个节点就叫做被删除节点的后继节点,用这个节点来代替被删除节点。 3、实验代码 #include 二叉树实验报告 09信管石旭琳 20091004418 一、实验目的: 1、理解二叉树的遍历算法及应用 2、理解哈夫曼树及其应用。 3、掌握哈夫曼编码思想。 二、实验内容: 1、建立二叉树二叉链表 2、实现二叉树递归遍历算法(中序、前序、后序) 3、求二叉树高度 4、求二叉树结点个数 5、求二叉树叶子个数 6、将序号为偶数的值赋给左子树 三、主要程序: #include wyf 实现二叉排序树的各种算法 一.需求分析 (1)系统概述: 本系统是针对排序二叉树设计的各种算法,提供的功能包括有:(1)插入新结点(2)前序、中序、后序遍历二叉树(3)中序遍历的非递归算法(4)层次遍历二叉树(5)在二叉树中查找给定关键字(函数返回值为成功1,失败0) 二.总体设计 (1)系统模块结构图 (2)数据结构设计 typedef struct BiTNode{ ElemType data; struct BiTNode *lchild,*rchild;//左右孩子指针} BiTNode,*BiTree; typedef BiTree SElemType; typedef BiTree QElemType; typedef struct { QElemType *base; // 初始化的动态分配存储空间 int front; // 头指针,若队列不空,指向队列头元素 int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置 }SqQueue; typedef struct { SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL SElemType *top; // 栈顶指针 int stacksize; // 当前已分配的存储空间,以元素为单位 }SqStack; // 顺序栈 Status InitStack(SqStack &S) { // 构造一个空栈S,该栈预定义大小为STACK_INIT_SIZE // 请补全代码 S.base = (SElemType * )malloc(STACK_INIT_SIZE * sizeof(SElemType)); if(!S.base) return (ERROR); S.top = S.base ; 数据结构二叉树基本操作 (1). // 对二叉树的基本操作的类模板封装 //------------------------------------------------------------------------------------------------------------------------ #include 数据结构课程设计---二叉排序树和平衡二叉树的判别 二叉排序树和平衡二叉树的判别 1引言 数据结构是软件工程的一门核心专业基础课程,在我们专业的课程体系中起着承上启下的作用,学好数据结构对于提高理论认知水平和实践能力有着极为重要的作用。学习数据结构的最终目的是为了获得求解问题的能力。对于现实世界中的问题,应该能从中抽象出一个适当的数据模型,该数学模型在计算机内部用相应的数据结构来表示,然后设计一个解此数学模型的算法,在进行编程调试,最后获得问题的解答。 本次课程设计的题目是对二叉排序树和平衡二叉树的扩展延伸应用。首先我们得建立一个二叉树,二叉树有顺序存储结构和链式存储结构两种存储结构,此次我选用的是二叉链表的存储结构。对于判断平衡二叉树,需要求出其每个叶子结点所在的层数,这里我采用的边遍历边求的方式,遍历采用的是先序遍历。二叉树的建立以及二叉排序树和平衡二叉树的判别中都用到了递归思想。 2需求分析 2.1在日常生活中,人们几乎每天都要进行“查找”工作。所谓“查找”即为 在一个含有众多的数据元素(或记录)的查找表中找出某个“特定的”数据元素(或记录),即关键字。 2.2本程序意为对一个已经建立的动态查找表——二叉树——判断其是否是二 叉排序树和平衡二叉树。 3数据结构设计 3.1抽象数据类型二叉树的定义如下: ADT BinaryTree{ 3.1.1数据对象D:D是具有相同特性的数据元素的集合。 3.1.2数据关系R: 若D=NULL,则R=NULL,称BinaryTree为空的二叉树; 若D!=NULL,则R={H},H是如下的二元关系: 3.1.2.1在D中存在唯一的称为根的数据元素root,它在关系H下无前驱; 3.1.2.2若D-{root}!=NULL,则存在D-{root}={Dl,Dr},且Dl与Dr相交为空; 3.1.2.3若Dl!=NULL,则Dl中存在唯一的元素xl, 《数据结构与数据库》 实验报告 实验题目 二叉树的基本操作及运算 一、需要分析 问题描述: 实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为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,失败。 二叉树的算法: 用扩展先序遍历序列创建二叉树; 递归遍历算法 中序非递归遍历层次遍历 二叉树深度的算法 实现代码如下: #include //以下为递归遍历算法 void PreOrder(BitTree root) /*先序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/ { if (root!=NULL) { Visit(root ->data); /*访问根结点*/ PreOrder(root ->LChild); /*先序遍历左子树*/ PreOrder(root ->RChild); /*先序遍历右子树*/ } } void InOrder(BitTree root) /*中序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/ { if (root!=NULL) { InOrder(root ->LChild); /*中序遍历左子树*/ Visit(root ->data); /*访问根结点*/ InOrder(root ->RChild); /*中序遍历右子树*/ } } void PostOrder(BitTree root) /* 后序遍历二叉树,root为指向二叉树(或某一子树)根结点的指针*/ { if(root!=NULL) { PostOrder(root ->LChild); /*后序遍历左子树*/ PostOrder(root ->RChild); /*后序遍历右子树*/ Visit(root ->data); /*访问根结点*/ } } //中序非递归遍历 void InOrder1(struct Node *head) { struct Node *p; struct Node *stack[20]; int top=0; p=head; while(p||top!=0) { while (p) 本程序由SOGOF完成 该完整程序主要是递归函数的使用及模板的使用,完成了对二叉树基本的链表操作,主要有二叉树的建立,前序、中序、后序遍历,求树的高度,每层结点数(包含树的最大宽度),左右结点对换,二叉树的内存释放,求解树的叶子数。 #include 二叉树的各种算法.txt 男人的承诺就像80 岁老太太的牙齿,很少有真的。你嗜烟成性的时候,只有三种人会高兴,医生你的仇人和卖香烟的。 /* 用函数实现如下二叉排序树算法: ( 1 )插入新结点 ( 2 )前序、中序、后序遍历二叉树 (3)中序遍历的非递归算法 (4)层次遍历二叉树 (5)在二叉树中查找给定关键字(函数返回值为成功1, 失败0) (6)交换各结点的左右子树 (7)求二叉树的深度 (8)叶子结点数 Input 第一行:准备建树的结点个数n 第二行:输入n 个整数,用空格分隔 第三行:输入待查找的关键字 第四行:输入待查找的关键字 第五行:输入待插入的关键字 Output 第一行:二叉树的先序遍历序列 第二行:二叉树的中序遍历序列 第三行:二叉树的后序遍历序列 第四行:查找结果 第五行:查找结果 第六行~第八行:插入新结点后的二叉树的先、中、序遍历序列第九行:插入新结点后的二叉树的中序遍历序列(非递归算法)第十行:插入新结点后的二叉树的层次遍历序列 第十一行~第十三行:第一次交换各结点的左右子树后的先、中、后序遍历序列第十四行~第十六行:第二次交换各结点的左右子树后的先、中、后序遍历序列第十七行:二叉树的深度 第十八行:叶子结点数 */ #include "stdio.h" #include "malloc.h" #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 typedef int Status; typedef int KeyType; #define STACK_INIT_SIZE 100 // 存储空间初始分配量 #define STACKINCREMENT 10 // 存储空间分配增量 #define MAXQSIZE 100 typedef int ElemType; typedef struct BiTNode{ ElemType data; struct BiTNode *lchild,*rchild;// 左右孩子指针 } BiTNode,*BiTree; Status SearchBST(BiTree T,KeyType key,BiTree f,BiTree &p) { if(!T){p=f;return FALSE;} else if(key==T->data){p=T;return TRUE;} else if(key 第六章树及二叉树 一、下面是有关二叉树的叙述,请判断正误 (√)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 (r ) 11、哈夫曼树中没有度为1的结点,所以必为满二叉树。 (r )12、在哈夫曼树中,权值最小的结点离根结点最近。 (r )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个结点只有非空右子树。东北大学计算机初试历年二叉树算法题目及解答
二叉树遍历算法的实现
实验三二叉树的基本操作
二叉树删除算法
二叉树的遍历算法实验报告
实现二叉排序树的各种算法
数据结构——二叉树基本操作源代码
数据结构课程设计---二叉排序树和平衡二叉树的判别
数据结构实验三——二叉树基本操作及运算实验报告
二叉树的各种遍历算法及其深度算法
二叉树基本操作经典实例
二叉树的各种算法
数据结构第6章二叉树作业与答案教材