树
实验五 树
一、实验目的
- 熟悉二叉树的链式存储结构
- 掌握二叉树的建立、深度优先递归遍历等算法
- 能够利用遍历算法实现一些应用
二、实验内容
- 已知二叉树采用二叉链表存储结构,如果左、右子树非空,且左子树根结点大于右子树根结点,则交换根结点的左、右子树。即按要求交换二叉树及子树的左、右子树。
- 采用二叉链表结构存储一棵二叉树,编写一个算法统计该二叉树中结点总数及叶子结点总数。
Tips
- 使用递归算法,判断条件交换左右字数即可
- 遍历过程中统计结点数,判断叶子结点数
Answer
5.1
//交换左右子树的程序代码
#include<stdio.h>
//#include<malloc.h>
#include<stdlib.h>
//二叉链表的结构类型定义
const int maxsize=1024;
typedef char datatype;
typedef struct node
{
datatype data;
struct node *lchild,*rchild;
}bitree;
bitree* creattree();
void preorder(bitree*);
void swap(bitree*);
void swap2(bitree*);
//void main()
int main()
{
bitree*pb;
pb=creattree();
preorder(pb);
printf("\n");
swap(pb);
preorder(pb);
printf("\n");
return 0;
}
//二叉树的建立
bitree*creattree()
{
char ch;
bitree*Q[maxsize];
int front,rear;
bitree*root,*s;
root=NULL;
front=1;rear=0;
printf("按层次输入二叉树,虚结点输入'@',以'#'结束输入:\n");
while((ch=getchar())!='#')
{
s=NULL;
if(ch!='@')
{
s=(bitree*)malloc(sizeof(bitree));
s->data=ch;
s->lchild=NULL;
s->rchild=NULL;
}
rear++;
Q[rear]=s;
if(rear==1)
{
root=s;
}
else
{
if(s&&Q[front])
{
if(rear%2==0)
{
Q[front]->lchild=s;
}
else
{
Q[front]->rchild=s;
}
}
if(rear%2==1)
{
front++;
}
}
}
return root;
}
//先序遍历按层次输出二叉树
void preorder(bitree*p)
{
if(p!=NULL)
{
printf("%c",p->data);
if(p->lchild!=NULL||p->rchild!=NULL)
{
printf("(");
preorder(p->lchild);
if(p->rchild!=NULL)printf(",");
preorder(p->rchild);
printf(")");
}
}
}
//交换左右子树
void swap(bitree*p)
{
bitree*t;
if(p!=NULL)
{
if(p->lchild!=NULL && p->rchild!=NULL && p->lchild->data > p->rchild->data)
{
t=p->lchild;
p->lchild=p->rchild;
p->rchild=t;
}
swap(p->lchild);
swap(p->rchild);
}
}
5.2
//统计结点总数及叶子结点总数的程序代码
#include<stdio.h>
//#include<malloc.h>
#include<stdlib.h>
//二叉链表的结构类型定义
const int maxsize=1024;
typedef char datatype;
typedef struct node
{
datatype data;
struct node *lchild,*rchild;
}bitree;
bitree*creattree();
void preorder(bitree*);
int countnode(bitree*);
int countleaf(bitree*);
//void main()
int main()
{
bitree*root;
int leafnum,nodenum;
root=creattree();
printf("删除子树之前的二叉树:");
preorder(root);
printf("\n");
nodenum=countnode(root);
printf("结点总数是:%d\n",nodenum);
leafnum=countleaf(root);
printf("叶子结点总数是:%d\n",leafnum);
return 0;
}
//建立二叉树
bitree*creattree()
{
datatype ch;
bitree*Q[maxsize];
int front,rear;
bitree*root,*s;
root=NULL;
front=1;rear=0;
printf("按层次输入结点值,虚结点输入'@',以换行符结束:");
while((ch=getchar())!='\n')
{
s=NULL;
if(ch!='@')
{
s=(bitree*)malloc(sizeof(bitree));
s->data=ch;
s->lchild=NULL;
s->rchild=NULL;
}
rear++;
Q[rear]=s;
if(rear==1)
{
root=s;
}
else
{
if(s&&Q[front])
{
if(rear%2==0)
{
Q[front]->lchild=s;
}
else
{
Q[front]->rchild=s;
}
}
if(rear%2==1)
{
front++;
}
}
}
return root;
}
//先序遍历输出二叉树
void preorder(bitree*p)
{
if(p!=NULL)
{
printf("%c",p->data);
if(p->lchild!=NULL||p->rchild!=NULL)
{
printf("(");
preorder(p->lchild);
if(p->rchild!=NULL) printf(",");
preorder(p->rchild);
printf(")");
}
}
}
//统计结点个数
int countnode(bitree *p)
{
static int node=0;
if(p!=NULL)
{
node++;
node = countnode(p->lchild);
node = countnode(p->rchild);
}
return node;
}
//统计叶子结点个数
int countleaf(bitree *p)
{
static int leaf=0;
{
if(p!=NULL)
{
leaf = countleaf(p->lchild);
if((p->lchild==NULL) && (p->rchild==NULL))
{
leaf = countleaf(p->rchild);
}
}
}
return leaf;
}