数据结构实验——二叉树及其应用

主要内容:

(1)按先序次序输入二叉树中结点的值,建立一棵以二叉链表作存储结构的二叉树,然后按先序、中序、后序、层序遍历这棵二叉树,并完成二叉树的相应信息的统计(如各种结点数目、二叉树的深度等);
(2)建立一棵二叉排序树,并对其遍历、结点统计、深度计算、数据查找等。

代码

Tree.cpp

#ifndef TR
#define TR
#include"include.h"
#include"Tree.h"
 
Status GetHead(SqQueue Q,QElemType &e){
	if(Q.front==Q.rear)return ERROR;
	e = Q.base[Q.front];
	return OK;
	
}
int QueueLength(SqQueue Q){
	return (Q.rear - Q.front+MAXSIZE)%MAXSIZE;
}

//队列 
Status InitQueue(SqQueue &Q){
	Q.base = (QElemType *)malloc(MAXSIZE * sizeof(QElemType));
	if(!Q.base)exit(OVERFLOW);
	Q.front = Q.rear = 0;
	return OK;
}
Status EnQueue(SqQueue &Q,QElemType e){
	if((Q.rear+1)%MAXSIZE==Q.front)return ERROR;
	Q.base[Q.rear]=e;
	Q.rear = (Q.rear+1)%MAXSIZE;
	return OK; 
}
Status DeQueue(SqQueue &Q,QElemType &e){
	if(Q.front == Q.rear)return ERROR;
	e = Q.base[Q.front];
	Q.front = (Q.front+1)%MAXSIZE;
	return OK;
}
Status DestroyQueue(SqQueue &Q){
	free(Q.base);
	Q.base = NULL;
	Q.front = Q.rear = 0;
	return OK;
}
Status QueuenEmpty(SqQueue Q){
	return (Q.front==Q.rear);
}
//根据先序和中序创建二叉树
void PreInCreat (BiTree &T,ElemType pre[],int in[],int l1,int h1,int l2,int h2){
	T = (BiTree)malloc(sizeof(BiNode));
	T->data = pre[l1];
	for(int i = l2;i<=h2;i++)
		{
		if(in[i]==pre[l1])break;
		if(i==l2) T->lchild = NULL;
		else PreInCreat(T->lchild,pre,in,l1+1,l1+(i-l2),l2,i-1);
		if(i==h2) T->rchild=NULL;
		else PreInCreat(T->rchild,pre,in,l1+(i-l2)+1,h1,i+1,h2);
		}
} 
//二叉排序树 
void CreateBiTree1(BiTree &root){
	ElemType x;
	root = NULL;
	cin>>x;
	while(x!=-1){
		insert(root,x);
		cin>>x;
	}
} 
void insert(BiTree &T,ElemType x){
	if(T==NULL){
		T = (BiTree)malloc(sizeof(BiTNode));
		T->data = x;
		T->lchild = T->rchild = NULL;
	}
	else{
		if(x<=T->data)insert(T->lchild,x);
		else insert(T->rchild,x);
	}
}
//查找递归算法 
BiTree SearchBST(BiTree L,TElemType x){
	if(L==NULL)return NULL;
	if(L->data==x)return L;
	else{
		if(x<L->data)
			return SearchBST(L->lchild,x);
		else
			return SearchBST(L->rchild,x);
	}
}
//查找非递归算法 
BiTree SearchBST2(BiTree L,ElemType x){
	BiTree p = L;
	while(p&&(x!=p->data))
		if(x<p->data) p = p->lchild;
		else	p = p->rchild;
	return p;
}
//二叉树 
Status  CreateBiTree(BiTree &T){
	char c;
	cin>>c; 
	if(c=='#')	T=NULL;
	else{
		if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))exit(OVERFLOW);
		T->data = c;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
	return OK;
}

void visit(TElemType e){
	cout<<e;
	printf("\n");
}
void visit2(ElemType e){
	cout<<e; 
	printf("\n");
}
Status PreOrderTraverse(BiTree T){
	if(T){
		visit(T->data);
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
	return OK;
}
Status InOrderTraverse(BiTree T){
		if(T){
		InOrderTraverse(T->lchild);
		visit(T->data);
		InOrderTraverse(T->rchild);
	}
	return OK;
}
Status InOrderTraverse2(BiTree L){
		if(L){
		InOrderTraverse2(L->lchild);
		visit2(L->data);
		InOrderTraverse2(L->rchild);
	}
	return OK;
}
Status PostOrderTraverse(BiTree T){
		if(T){
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		visit(T->data);
	}
	return OK;
}
Status LevelOrderTraverse(BiTree T){
	SqQueue Q;
	QElemType b;
	InitQueue(Q);
	if(T!=NULL){
		EnQueue(Q,T);
		while(!QueuenEmpty(Q)){
			DeQueue(Q,b);
			visit(b->data);
			if(b->lchild!=NULL)
				EnQueue(Q,b->lchild);
			if(b->rchild!=NULL)
				EnQueue(Q,b->rchild);
		}
	}
	return OK;
}
int Depth(BiTree T){
	int depthval = 0;
	int depthLeft,depthRight;
	if(!T) depthval = 0;
	else{
		depthLeft=Depth(T->lchild);
		depthRight = Depth(T->rchild);
		depthval = 1 + (depthLeft>depthRight?depthLeft:depthRight);
	}
	return depthval;
} 
int count_n(BiTree T){
	int num1,num2,num;
	if(T==NULL)num = 0;
	else{
		num1 = count_n(T->lchild);
		num2 = count_n(T->rchild);
		num = num1 + num2 +1;
	}
	return num;
}
int countleaft(BiTree T){//单独统计叶子结点 
	int num1,num2,num;
	if(T==NULL)num=0;
	else{
		if((T->lchild==NULL)&&(T->rchild==NULL))
			num = 1;
			else{
				num1 = countleaft(T->lchild);
				num2 = countleaft(T->rchild);
				num = num1 + num2;
			}
	}
	return num;
}
void count(BiTree L,int &n,int &n0,int &n1,int &n2)//统计所有节点数目 
{
	if(L)
	{
		n++;//所有节点 
		if(!L->lchild && !L->rchild)//结点 
			n0++;
		if((!L->lchild && L->rchild)||(!L->rchild && L->lchild))	//单叶子 
			n1++;
		if(L->lchild&&L->rchild)//双叶子 
			n2++;
		count(L->lchild,n,n0,n1,n2);
		count(L->rchild,n,n0,n1,n2);
	} 
}
void change_left_right(BiTree T){
	BiTree temp;
	if(T){
		change_left_right(T->lchild);
		change_left_right(T->rchild);
		temp = T->lchild;T->lchild = T->rchild;T->rchild = temp;
	}
} 
#endif

main.cpp

#include"include.h"
#include"Tree.h"

int main() {
	BiTree T,L;
	int n;
	printf("现在你对二叉树有以下操作:\n0——退出\n1——创建\n2——先序遍历\n3——中序遍历\n4——后序遍历\n5——层序遍历\n6——深度\n7——结点\n8——叶子节点\n9——统计所有结点\n"); 
	cin>>n;
	fflush(stdin);
	while(n){
		switch  (n){
			case 1:{
				printf("现在开始创建二叉树,以#作为结束符\n");
				CreateBiTree(T);
				break;
			}
			case 2:{
				printf("开始先序遍历:\n");
				PreOrderTraverse(T);
				break;
			}
			case 3:{
				printf("开始中序遍历:\n");
				InOrderTraverse(T);
				break;
			}
			case 4:{
				printf("开始后序遍历:\n");
				PostOrderTraverse(T);
				break;
			}
			case 5:{
				printf("开始层序遍历:\n");
				LevelOrderTraverse(T);
				printf("\n");
				break;
			}
			case 6:{
				int depth = Depth(T);
				printf("现在树的深度是:%d\n",depth);
				break;
			}
			case 7:{
				int count = count_n(T);
				printf("现在树的结点是:%d\n",count);
				break;
			}
			case 8:{
				int count = countleaft(T);
				printf("现在树的叶子结点是:%d\n",count);
				break;
			} 
			case 9:{
				int n=0,n0=0,n1=0,n2=0;
				count(T,n,n0,n1,n2);
				printf("节点:%d,结点:%d,单叶子:%d,双叶子:%d\n",n,n0,n1,n2);
				break;
			}
		}
		printf("继续操作:\n");
		scanf("%d",&n);
	} 
	printf("现在进行二叉排序树,请输入数字,以-1作为结尾\n");
	CreateBiTree1(L);
	printf("现在你可以对二叉排序树做以下操作:\n0——退出\n1——结点统计\n2——深度计算\n3——数据查找\n4——按序遍历\n5——统计所有的节点\n");
	cin>>n;
	fflush(stdin);
	while(n){
		switch(n){
			case 1:{
				int count = countleaft(L);
				printf("现在树的叶子结点是:%d\n",count);
				break;
			}
			case 2:{
				int depth = Depth(L);
				printf("现在树的深度是:%d\n",depth);
				break;
			}
			case 3:{
				BiTree E=NULL;
				ElemType x;
				printf("请输入需要查找的数据:\n");
				cin>>x;
				E = SearchBST(L,x);
				if(E==NULL)printf("查找失败!\n");
				else printf("查找成功!\n"); 
				break;
			}
			case 4:{
				printf("按序遍历:\n");
				InOrderTraverse2(L);
				printf("\n");
				break;
			}
			case 5:{
				int n=0,n0=0,n1=0,n2=0;
				count(L,n,n0,n1,n2);
				printf("节点:%d,结点:%d,单叶子:%d,双叶子:%d\n",n,n0,n1,n2);
				break;
			}
			default:{
				printf("输入有误!\n");
				break;
			}
		}
		printf("继续操作:\n");
		cin>>n;
		fflush(stdin);
	}
	return 0;
}

Tree.h

#ifndef TREE
#define TREE

#define MAX_TREE_SIZE 100
#define MAXSIZE 100
typedef char TElemType;
typedef int ElemType;
typedef int Status;
//typedef TElemType SqBiTree[MAX_TREE_SIZE];
//SqBiTree bt;
//链式存储
typedef struct BiTNode{
	TElemType data;
	struct BiTNode *lchild,*rchild;
}BiNode,*BiTree;
typedef BiTree QElemType;

typedef struct{
	QElemType *base;
	int front;
	int rear;
}SqQueue;
Status InitQueue(SqQueue &Q);
//int QueueLength(SqQueue Q);
Status EnQueue(SqQueue &Q,QElemType e);
Status DeQueue(SqQueue &Q,QElemType &e);
Status DestroyQueue(SqQueue &Q);
//Status GetHead(SqQueue Q,QElemType &e);
Status QueuenEmpty(SqQueue Q);

Status  CreateBiTree(BiTree &T);
void PreInCreat (BiTree &T,ElemType pre[],int[],int l1,int h1,int l2,int h2);
void visit(TElemType e);
Status PreOrderTraverse(BiTree T);
Status InOrderTraverse(BiTree T);
Status PostOrderTraverse(BiTree T);
Status LevelOrderTraverse(BiTree T); 
int Depth(BiTree T);
int count_n(BiTree T);
int countleaft(BiTree T);
void change_left_right(BiTree T);
void CreateBiTree1(BiTree &root);
void insert(BiTree &T,ElemType x);
BiTree SearchBST2(BiTree L,ElemType x);
BiTree SearchBST(BiTree L,TElemType x);
void insert(BiTree &T,ElemType x);
void CreateBiTree1(BiTree &root);
Status InOrderTraverse2(BiTree L);
void visit2(ElemType e);
Status GetHead(SqQueue Q,QElemType &e);
int QueueLength(SqQueue Q); 
void count(BiTree L,int &n,int &n0,int &n1,int &n2); 
#endif

include.h


#ifndef INCLUDE
#define INCLUDE
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define OK 1
#define ERROR -1


#endif

最后的话

代码仅做参考和本人的学习记录,请不要用于其他途径。
刚写博客不久,没有注释说明,请谅解,学艺不精,请指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值