二叉树的有关操作

一、目的要求

(1)掌握二叉树的存储实现。

(2)掌握二叉树的遍历思想。

(3)掌握二叉树的常见算法的程序实现。

二、实验内容

(1)输入字符序列,建立二叉链表。

(2)中序遍历二叉树:采用递归算法和非递归算法。(最好也能实现先序,后序非递归算法)

(3)求二叉树的高度和叶子个数。

(4) 借助队列实现二叉树的层次遍历。 

(5)综合训练:为N个权值设计哈夫曼编码。(选做)

#include <stdio.h>
#include <malloc.h>
#include <math.h> 
#define MaxSize 100
#define MaxWidth 40
typedef char ElemType;       // 定义数据类型
typedef struct tnode         //定义节点
{
	ElemType data;
	struct tnode *lchild,*rchild;  //两个指针指向左右孩子
} BTNode;                          //节点类型
char result[100]={0};                        //记录层次遍历的结果

void CreateBTree(BTNode * &bt,char *str)          //   由str创建二叉链bt    
{
	BTNode *St[MaxSize],*p=NULL;
	int top=-1,k,j=0;        
	char ch;
	bt=NULL;                             //初始化
	ch=str[j];
	while (ch!='\0')        //str未扫描完时循环
	{
		switch(ch) 
		{
			case '(':top++;St[top]=p;k=1; break; /*为左孩子结点*/
			case ')':top--;break;
			case ',':k=2; break;                    /*为孩子结点右结点*/
			default:p=(BTNode *)malloc(sizeof(BTNode));p->data=ch;p->lchild=p->rchild=NULL;
				if (bt==NULL)                   /* *p为二叉树的根结点 */
					bt=p;
				else         /*已建立二叉树根结点*/
				{ 	switch(k) 
					{
						case 1:St[top]->lchild=p;break;
						case 2:St[top]->rchild=p;break;
					}
				}
		}
	j++;
	ch=str[j];
	}
}

void DispBTree(BTNode *bt) /*以括号表示法输出二叉树*/
{
	if (bt!=NULL)
	{ 
		printf("%c",bt->data);
		if (bt->lchild!=NULL || bt->rchild!=NULL)
		{ 
			printf("(");
			DispBTree(bt->lchild);  /*递归处理左子树*/
			if (bt->rchild!=NULL) 
				printf(",");
			DispBTree(bt->rchild);  /*递归处理右子树*/
			printf(")");
		}
	}
}
void DispBTree1(BTNode *bt)  /*以凹入表示法输出一棵二叉树*/
{
	BTNode *St[MaxSize],*p;
	int Level[MaxSize][2],top=-1,n,i,width=4;
	char type;  /*取值L表示为左结点,R表示为右结点,B表示为根结点*/
	if (bt!=NULL)
	{ 
		top++;
		St[top]=bt;      /*根结点入栈*/
		Level[top][0]=width;
		Level[top][1]=2;    /*2表示是根*/
		while (top>-1)
		{ 
			p=St[top];     /*退栈并凹入显示该结点值*/
			n=Level[top][0];
			switch(Level[top][1])
			{
				case 0:type='L';break;  /*左结点之后输出(L)*/
				case 1:type='R';break;  /*右结点之后输出(R)*/
				case 2:type='B';break;  /*根结点之后前输出(B)*/
			}
			for (i=1;i<=n;i++)   /*其中n为显示场宽,字符以右对齐显示*/
				printf(" ");
			printf("%c(%c)",p->data,type);
			for (i=n+1;i<=MaxWidth;i+=2)
				printf("━");
			printf("\n");
			top--;
			if (p->rchild!=NULL)
			{       /*将右子树根结点入栈*/
				top++;
				St[top]=p->rchild;
				Level[top][0]=n+width; /*场宽增width,即缩width格后再输出*/
				Level[top][1]=1;  /*1表示是右子树*/
			}
			if (p->lchild!=NULL)
			{       /*将左子树根结点入栈*/
				top++;
				St[top]=p->lchild;
				Level[top][0]=n+width;  /*显示场宽增width*/
				Level[top][1]=0;        /*0表示是左子树*/
			}
		}
	}
}
void levelTraverse(BTNode *bt)
{
	BTNode Queue[20];            
	BTNode *p;
	int i=0;
	p=bt;/*根指针入队*/
	int front=0,rear=0;  /*表示队头指针和队尾指针*/
	if(p)
	{
		Queue[rear]=*p;
		rear=(rear+1)%20;         /*队尾指针加一对20取余,可实现循环队列,合理利用空间*/
		while(front!=rear)        /*队不空*/
		{
			*p=Queue[front];          /*出队,将值赋给p*/
			printf("%c",p->data);
			result[i++]=p->data; 
			front=(front+1)%20;
			if(p->lchild)            /*如果p有左子树,将左子树入队*/
			{
				Queue[rear]=*p->lchild;
				rear=(rear+1)%20;
			}
			if(p->rchild)                  /*如果p有右子树,将右子树入队*/
			{
				Queue[rear]=*p->rchild;
				rear=(rear+1)%20;
			}
		}
	}
}

int  main()
{
	int h=0,times=1,r=0,figure,Leaf;//times表示层次,h高度,figure结点个数
	BTNode *bt;
	CreateBTree(bt,"A(B(D(H,I),E(J,K)),C(F(L),G))"); /*构造二叉树*/
	printf("二叉树bt:");
	DispBTree(bt);printf("\n");
	printf("bt凹入表示:\n");
	DispBTree1(bt);printf("\n");
	printf("层次遍历:\n"); 
	levelTraverse(bt);
	printf("\n");
    while(times<=h)//控制输出
	{ 
		for(int i=0;i<pow(2.0,h-times);i++)
		printf(" ");//控制每行开头的空格
		for(int j=0;j<pow(2.0,times-1);j++,r++)//控制每行输出个数
		{ 
			if(result[r]!='*')
				printf("%c",result[r]);
			else
				printf(" ");
			for(int k=0;k<pow(2.0,h-times+1)-1;k++)
				printf(" ");//每行内部空格控制
		}
		printf("\n");
		times++;
	}//while
	scanf("%d",&h);

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值