《软件技术基础》实验指导 实验五

实验五 树

一、实验目的

  1. 熟悉二叉树的链式存储结构
  2. 掌握二叉树的建立、深度优先递归遍历等算法
  3. 能够利用遍历算法实现一些应用

二、实验内容

  1. 已知二叉树采用二叉链表存储结构,如果左、右子树非空,且左子树根结点大于右子树根结点,则交换根结点的左、右子树。即按要求交换二叉树及子树的左、右子树。
  2. 采用二叉链表结构存储一棵二叉树,编写一个算法统计该二叉树中结点总数及叶子结点总数。

Tips

  1. 使用递归算法,判断条件交换左右字数即可
  2. 遍历过程中统计结点数,判断叶子结点数

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;
}
posted @ 2017-12-04 20:01  VanLion  阅读(353)  评论(0编辑  收藏  举报