二叉树的各种算法
![二叉树的各种算法](https://img.360docs.net/img66/1bygslya6pcpfpeyqr4y10gnu1gb9qq7-61.webp)
![二叉树的各种算法](https://img.360docs.net/img66/1bygslya6pcpfpeyqr4y10gnu1gb9qq7-52.webp)
二叉树的各种算法.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
return(SearchBST(T->rchild,key,T,p));
}
Status InsertBST(BiTree &T,ElemType e)
{
BiTree s,p; if(!SearchBST(T,e,NULL,p))
{ s=(BiTree)malloc(sizeof(BiTNode)); s->data=e;s->lchild=s->rchild=NULL;
if(!p)T=s;
else if(e
else p->rchild=s; return TRUE;
}
else return FALSE;
}
Status PrintElement( ElemType e ) { // 输出元素e 的值
printf("%d ", e );
return OK;
}// PrintElement
Status PreOrderTraverse( BiTree T, Status(*Visit)(ElemType) ) {
// 前序遍历二叉树 T 的递归算法,对每个数据元素调用函数
// 补全代码 , 可用多个语句
if(T)
{ if(Visit(T->data))
if(PreOrderTraverse(T->lchild,Visit))
if(PreOrderTraverse(T->rchild,Visit))return OK; return
ERROR;
}
else return OK;
} // PreOrderTraverse
Status InOrderTraverse( BiTree T, Status(*Visit)(ElemType) )
{
// 中序遍历二叉树 T 的递归算法,对每个数据元素调用函数
// 补全代码 , 可用多个语句
if(T)
{ if(InOrderTraverse(T->lchild,Visit))
if(Visit(T->data)) if(InOrderTraverse(T->rchild,Visit))
return OK;
return ERROR;
}
else return OK;
} // InOrderTraverse
Status PostOrderTraverse( BiTree T, Status(*Visit)(ElemType) ) {
// 后序遍历二叉树 T 的递归算法,对每个数据元素调用函数
// 补全代码 , 可用多个语句
if(T)
{
if(PostOrderTraverse(T->lchild,Visit))
if(PostOrderTraverse(T->rchild,Visit)) if(Visit(T->data))return OK; return
ERROR;
} else return OK;
} // PostOrderTraverse
Status Putout(BiTree T)
{
PreOrderTraverse(T,PrintElement);
printf("\n");
InOrderTraverse(T, PrintElement);
printf("\n");
PostOrderTraverse(T,PrintElement);
printf("\n");
Visit 。
Visit 。
Visit 。
return OK;
}
// ............................................... 非递归算法
struct SqStack
{
BiTree *base; // 在栈构造之前和销毁之后,base 的值为NULL
BiTree *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈
Status InitStack(SqStack &S)
{
S.base=(BiTree *)malloc(STACK_INIT_SIZE*sizeof(BiTree));
if(!S.base)return ERROR;
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status Push(SqStack &S,BiTree e)
{
if((S.top-S.base)>=S.stacksize)
{
S.base=(BiTree*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(BiTree));
if(!S.base)return ERROR;
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return OK;
}
Status Pop(SqStack &S,BiTree &e)
{
if(S.top==S.base)return ERROR;
e=*--S.top;
return OK;
}
Status StackEmpty(SqStack S)
{ // 若栈S为空栈,则返回TRUE否则返回FALSE if(S.top-S.base==0)return TRUE; else return FALSE;
}
Status InOrderTraverse1(BiTree T,Status(*Visit)(ElemType e),SqStack S) { BiTree p;
InitStack(S);p=T; while(p||!StackEmpty(S))
{
if(p){Push(S,p);p=p->lchild;}
else
{
Pop(S,p); if(!Visit(p->data))return ERROR; p=p->rchild;
}
}
return OK;
}
II ............................ 层次遍历
typedef struct
{
BiTree *base; II
初始化的动态分配存储空间
int front; II 头指针, 若队列不空, 指向队列头元素
int rear; II 尾指针, 若队列不空, 指向队列尾元素的下一个位置
}SqQueue;
Status InitQueue(SqQueue &Q)
{
Q.base=(BiTree*)malloc(MAXQSIZE*sizeof(BiTree));
if(!Q.base)return ERROR;
Q.front=Q.rear=0;
return OK;
int QueueLength(SqQueue Q)
{
// 返回Q 的元素个数
// 请补全代码
return(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
Status EnQueue(SqQueue &Q,BiTree e)
{
//插入元素e为Q的新的队尾元素
// 请补全代码
if((Q.rear+1)%MAXQSIZE==Q.front)return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}
Status DeQueue(SqQueue &Q,BiTree &e)
{
//若队列不空,则删除Q的队头元素,用e返回其值,并返回0K;否则返回ERROR // 请补全代码if(Q.front==Q.rear)return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
Status LevelTraverse(BiTree T,SqQueue Q)// 层次遍历二叉树
{
InitQueue(Q);
BiTree p;
p=T;
if(T)EnQueue(Q,T);
// printf("%d",QueueLength(Q));
while(QueueLength(Q)!=0)
{
DeQueue(Q,p); // 根结点出队
printf("%d ",p->data); // 输出数据
if(p->lchild)EnQueue(Q,p->lchild); // 左孩子进队
if(p->rchild)EnQueue(Q,p->rchild); // 右孩子进队
}
return OK;
void Change(BiTree T)
{
BiTNode *p;
if(T) {p=T->lchild;
T->lchild=T->rchild; T->rchild=p;
Change(T->lchild);
Change(T->rchild); }
// return OK;
}
int BTreeDepth(BiTree T)
// 求由BT 指针指向的一棵二叉树的深度
{
// int dep1,dep2;
if(T!=NULL)
{
// 计算左子树的深度
int dep1=BTreeDepth(T->lchild);
// 计算右子树的深度
int dep2=BTreeDepth(T->rchild);
// 返回树的深度if(dep1>dep2) return dep1+1; else return dep2+1;
}
else return 0;
}
// .............. 叶子结点数
Status yezhi(BiTree T,SqQueue Q)
{
int i=0;
InitQueue(Q);
BiTree p;
p=T;
if(T)EnQueue(Q,T);
// printf("%d",QueueLength(Q)); while(QueueLength(Q)!=0)
{
DeQueue(Q,p); if(p->lchild)EnQueue(Q,p->lchild); if(p->rchild)EnQueue(Q,p->rchild);
if(!p->lchild&&!p->rchild)
i++;
}
return i;
}
int main() // 主函数
{
SqStack S;
SqQueue Q,Q3;
BiTree T=NULL,f,p;
int i,n,e,a,b,c;
scanf("%d",&n); for(i=0;i scanf("%d",&e); InsertBST(T,e); } scanf("%d",&a);scanf("%d",&b);scanf("%d",&c);Putout(T); printf("%d\n",SearchBST(T,a,f,p)); printf("%d\n",SearchBST(T,b,f,p)); 二叉树的各种算法.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. 掌握二叉树的存储实现 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; } /*---------------------------------------------递归部分-------------------------------------------*/ 二叉树的基本操作实现及其应用 一、实验目的 1.熟悉二叉树结点的结构和对二叉树的基本操作。 2.掌握对二叉树每一种操作的具体实现。 3.学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。 4.会用二叉树解决简单的实际问题。 二、实验内容 设计程序实现二叉树结点的类型定义和对二叉树的基本操作。该程序包括二叉树结构类型以及每一种操作的具体的函数定义和主函数。 1 按先序次序建立一个二叉树, 2按(A:先序 B:中序 C:后序)遍历输出二叉树的所有结点 以上比做,以下选做 3求二叉树中所有结点数 4求二叉树的深度 三、实验步骤 ㈠、数据结构与核心算法的设计描述 /* 定义DataType为char类型 */ typedef char DataType; /* 二叉树的结点类型 */ typedef struct BitNode { DataType data; struct BitNode *lchild,*rchild; }*BitTree; 相关函数声明: 1、/* 初始化二叉树,即把树根指针置空 */ void BinTreeInit(BitTree *BT) { BT=(BitTree)malloc(sizeof(BitNode)); BT->data=NULL; cout<<"二叉树初始化成功!"< 二叉树层次遍历算法实现 问题描述 对任意输入的表示某二叉树的字符序列,完成二叉树的层次遍历算法,并输出其遍历结果。 注:所需Queue ADT的实现见附录。 输入描述 从键盘上输入一串字符串,该字符串为二叉树的先序遍历结果,其中如果遍历到空树时用字符”#”代替。 输出描述 从显示器上输出二叉树的按层次遍历结果。 输入与输出示例 输入: +A##/*B##C##D## 输出: +A/*DBC 输入: ABD##GJ###CFH##I### 输出: ABCDGFJHI 附录(仅供参考): #include //注:需要定义ElementType类型,如果是二叉树, // 则应定义为指向二叉树中结点的指针类型 //格式如: // typedef Tree ElementType; // 队列存储结构采用循环队列 struct QueueRecord; typedef struct QueueRecord *Queue; int IsEmpty(Queue Q); int IsFull(Queue Q); Queue CreateQueue(int MaxElements); void DisposeQueue(Queue Q); void MakeEmpty(Queue Q); int Enqueue(ElementType X, Queue Q); ElementType Front(Queue Q); int Dequeue(Queue Q, ElementType &X); #define MinQueueSize ( 5 ) struct QueueRecord { int Capacity; int Front; int Rear; ElementType *Array; }; int IsEmpty(Queue Q) { return ((Q->Rear + 1)% Q->Capacity == Q->Front); } int IsFull(Queue Q) { return ((Q->Rear + 2) % Q->Capacity == Q->Front); } Queue CreateQueue(int MaxElements) { Queue Q; if (MaxElements < MinQueueSize) return NULL; Q = (Queue)malloc(sizeof(struct QueueRecord)); [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, 实验6 实验目的: 1、掌握二叉树的所有算法 2、熟悉计算机英语和术语 实验步骤: 1、二叉树算法的模拟 2、完型填空 3、翻译 具体要求: 一、设计一个完整的程序,实现二叉树的各种算法 要求:/*用函数实现如下二叉排序树算法: (1)插入新结点 (2)前序、中序、后序遍历二叉树 (3)中序遍历的非递归算法 (4)层次遍历二叉树 (5)在二叉树中查找给定关键字(函数返回值为成功1,失败0) (6)交换各结点的左右子树 (7)求二叉树的深度 (8)叶子结点数 输入: 第一行:准备建树的结点个数n 第二行:输入n个整数,用空格分隔 第三行:输入待查找的关键字 第四行:输入待查找的关键字 第五行:输入待插入的关键字 输出: 第一行:二叉树的先序遍历序列 第二行:二叉树的中序遍历序列 第三行:二叉树的后序遍历序列 第四行:查找结果 第五行:查找结果 第六行~第八行:插入新结点后的二叉树的先、中、序遍历序列第九行:插入新结点后的二叉树的中序遍历序列(非递归算法) 代码: #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 二叉树删除算法 姓名:李晓娜学号:20122593 班级:软件一班 1、问题描述 使用算法实现二叉树的建立及删除。 2、解题思路 二叉树的删除操作比较复杂,主要分三种情况:1、删除没有子节点的节点,2、删除只有一个节点的节点(其中有分为两种情况),3、删除有两个节点的节点。 首先看第一种情况:(删除没有子节点的节点) 删除没有子节点的节点只需要将被删除节点的父节点指向空即可 第二种情况:(删除只有一个子节点的节点) 删除有一个子节点的节点,只需要将被删除节点的父节点指向删除节点的子节点即可 第三种情况:(删除有两个子节点的节点,即左右子树都非空) 删除有两个子节点的节点,到底谁来替代被删除的节点的位置呢?是左节点,还是右节点,代替以后这个子节点的子节点应该怎么安排?一系列的问题都出来了。。。简便的方法就是要找一个节点代替这个被删除的节点,这就要从二叉搜索树的定义来看。因为二叉搜索树是有序的,我们要找的节点在这棵树上,而且这个节点要比被删除的左节点大,比右节点小。先看看这个已被删除节点的右节点为根的子树的所有节点的值都要比被删除节点大,这是二叉搜索树定义的,但是要在这个集合中找到最小的一个,来代替被删除的节点,那就要在这棵子树上一直往左找。这个节点比被删除的节点的右节点小,且比左节点大,那这个节点就叫做被删除节点的后继节点,用这个节点来代替被删除节点。 3、实验代码 #include 二叉树实验报告 09信管石旭琳 20091004418 一、实验目的: 1、理解二叉树的遍历算法及应用 2、理解哈夫曼树及其应用。 3、掌握哈夫曼编码思想。 二、实验内容: 1、建立二叉树二叉链表 2、实现二叉树递归遍历算法(中序、前序、后序) 3、求二叉树高度 4、求二叉树结点个数 5、求二叉树叶子个数 6、将序号为偶数的值赋给左子树 三、主要程序: #include 二叉树的算法: 用扩展先序遍历序列创建二叉树; 递归遍历算法 中序非递归遍历层次遍历 二叉树深度的算法 实现代码如下: #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) 二叉树的各种算法.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个结点只有非空右子树。 3.2.5 二叉排序树 在这一部分我们要掌握的是二叉排序树的概念、查找、插入和删除操作。在以下的知识点中,二叉排序树的删除相对于其他知识点要复杂一些,但只要掌握了规则,题目还是很容易解决的。下面我们先分别给出各部分的介绍及算法实现,再对一些典型题目进行解析。 (1)二叉排序树 二叉排序树是一种常用的动态查找表,下面首先给出它的非递归形式。 二叉排序树是一棵二叉树,它或者为空,或者具有如下性质: ①任一非终端结点若有左孩子,则该结点的关键字值大于其左孩子结点的关键字值。 ②任一非终端结点若有右孩子,则该结点的关键字值小于其右孩子结点的关键字值。 二叉排序树也可以用递归的形式定义,即二叉排序树是一棵树,它或者为空,或者具有如下性质: ①若它的左子树非空,则其左子树所有结点的关键字值均小于其根结点的关键字值。 ②若它的右子树非空,则其右子树所有结点的关键字值均大于其根结点的关键字值。 ③它的左右子树都是二叉排序树。 例如,由关键字值序列(62,15,68,46,65,12,57,79,35)构成的一棵二叉排序树如图3-38所示。 如果对上述二叉排序树进行中序遍历可以得到一个关键字有序序列 (12,15,35,46,57,62,65,68,79),这是二叉排序树的一个重要特征,也正是由此将其称为"二叉排序树"。 (2)二叉排序树的查找 二叉排序树的结构定义中可看到:一棵非空二叉排序树中根结点的关键字值大于其左子树上所有结点的关键字值,而小于其右子树上所有结点的关键字值。因此在二叉排序树中查找一个关键字值为k的结点的基本思想是:用给定值k与根结点关键字值比较,如果k小于根结点的值,则要找的结点只可能在左子树中,所以继续在左子树中查找,否则将继续在右子树中查找,依此方法,查找下去,至直查找成功或查找失败为止。二叉排序树查找的过程描述如下: ①若二叉树为空树,则查找失败; ②将给定值k与根结点的关键字值比较,若相等,则查找成功; ③若根结点的关键字值小于给定值k,则在左子树中继续搜索; ④否则,在右子树中继续查找。 假定二叉排序树的链式存储结构的类型定义如下: 1.typedef struct linklist{ 2.keytype key; 3.anytype otherelem; 4.struct linklist*lchild; 5.struct linklist*rchild; 6.}Bin_Sort_Tree_Linklist,*Bin_Sort_Tree; 一、下面是有关二叉树的叙述,请判断正误() (). 若二叉树用二叉链表作存贮结构,则在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 《数据结构与数据库》 实验报告 实验题目 二叉树的基本操作及运算 一、需要分析 问题描述: 实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为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"stdio.h" #include"malloc.h" #define maxsize 10 #define NULL 0 typedefstruct node{ char data; struct node *lchild,*rchild; }Bintree; Bintree *Q[maxsize]; Bintree *creatree(){ charch; int front=1,rear=0; Bintree *T,*S; T=NULL; ch=getchar(); while(ch!='#'){ S=NULL; if(ch!='@'){ S=(Bintree *)malloc(sizeof(Bintree)); S->data=ch; S->lchild=S->rchild=NULL; } rear++; Q[rear]=S; if(rear==1) T=S; else{ if(S!=NULL&&Q[front]!=NULL) if(rear%2==0) Q[front]->lchild=S; else Q[front]->rchild=S; if(rear%2==1) front++; } ch=getchar(); } return T; } voidprintree(Bintree *T){ if(T){ printf("%2c",T->data); printree(T->lchild); printree(T->rchild); } } voidchangetree(Bintree *T){ if(T){ Bintree *A; changetree(T->lchild); 齐鲁工业大学实验报告成绩 课程名称数据结构指导教师单健芳实验日期 院(系)信息学院专业班级计科(嵌入)14-1 实验地点 学生姓名高晨悦学号201403071007 同组人无 实验项目名称二叉树的递归算法 一、实验目的和要求 1.实现二叉树的先序,中序与后序遍历的递归算法与非递归算法。 2.求二叉树的结点个数,叶子结点个数,二叉树的高度,度为2的结点个数。 二、实验环境 微型计算机vc 6.0 三、实验内容 1.实现二叉树的先序,中序与后序遍历的递归算法与非递归算法。 2.求二叉树的结点个数,叶子结点个数,二叉树的高度,度为2的结点个数。 四、实验步骤 一.实验内容 1.实现二叉树的先序,中序与后序遍历的递归算法与非递归算法。 2.求二叉树的结点个数,叶子结点个数,二叉树的高度,度为2的结点个数。二.程序的设计思想 1实现二叉树的先序,中序与后序遍历的递归算法与非递归算法。 先构造二叉树,根据先序遍历的思想,输入根后,再输入左子树,直至左子树为空则输入上一层右字树。 (1)二叉树的非递归遍历是用显示栈来存储二叉树的结点指针,先序遍历时,按二叉树前序遍历的顺序访问结点,并将结点的指针入栈,直到栈顶指针指向结点的左指针域为空时取出栈顶指针并删除栈顶指针,访问刚取出的指针指向的结点的右指针指向的结点并将其指针入栈,如此反复执行则为非递归操作。 (2)二叉树的递归遍历:若二叉树为空,则空操作 先序遍历: (a)访问根结点; (b)先序遍历左子树; (c)先序遍历右子树。 中序遍历: (a)中序遍历左子树; (b)访问根结点; (c)中序遍历右子树 后序遍历: (a)后序遍历左子树; (b)后序遍历右子树; (c)访问根结点。 2.求二叉树的结点个数,叶子结点个数,二叉树的高度,度为2的结点个数。 (1)求二叉树的叶子结点个数:先分别求得左右子树中个叶子结点的个数,再计算出两者之和即为二叉树的叶子结点数。 (2)二叉树的结点个数之和:先分别求得左子树右子树中结点之和,再计算两者之和即为所求。 (3)二叉树的高度:首先判断二叉树是否为空,若为空则此二叉树高度为0,。否则,就先分别求出左右子树的深度进行比较,取较大的树加一即为所求。 (4)二叉树的度为2的结点个数:计算有左右孩子的结点个数,即为度为2的结点个数。三.编程过程中遇到的问题及解决办法二叉树的各种算法
二叉树排序算法
实验三 二叉树的基本操作实现及其应用
二叉树的层次遍历算法
东北大学计算机初试历年二叉树算法题目及解答
二叉树遍历算法的实现
设计一个完整的程序,实现二叉树的各种算法
二叉树删除算法
二叉树的遍历算法实验报告
二叉树的各种遍历算法及其深度算法
二叉树的各种算法
数据结构第6章二叉树作业与答案教材
二叉树
二叉树习题(answer)
数据结构实验三——二叉树基本操作及运算实验报告
编写算法交换二叉树中所有结点的左
数据结构二叉树的递归算法实验报告