`

二叉树

阅读更多
#include <stdio.h>
#include <malloc.h>
#define MaxSize 100

typedef char ElemType;
typedef struct Node{
	ElemType data;
	struct Node *lchild;
	struct Node *rchild;
} BTree;

/**
*由括号表示法创建链式二叉树
*例如:A(B(D(,G)),C(E,F))
*      创建结点A,A为根结点;A压栈,k=1;创建B,B为A的左孩子;B压栈,k=1;
*      创建D,D为B的左孩子;D压栈,k=1;k=2;G为D的右孩子;D出栈;B出栈;k=2;
* C为A的右孩子;C压栈,k=1;创建E,E为C的左孩子;k=2;F为C的右孩子;C出栈;A出栈
*/
void CreateBTree(BTree *&b,char *str){
	BTree *st[MaxSize]; int top=-1;  //st作为栈,其元素为BTree *,st存储树节点
	int k;                           //k标记是左孩子还是右孩子  
	int i=0; char ch=str[i];          //ch为遍历元素str所处的元素,i为对应位置
	b=NULL;	
	BTree *p=NULL;
	while (ch!='\0'){
   	   	switch(ch) {
	      	case '(':top++;st[top]=p;k=1; break;//接下来创建左孩子,父亲压栈
		    case ')':top--;break;               //右孩子创建完毕,父亲出栈
	    	case ',':k=2; break;                //左孩子创建完毕,接下来创建右孩子
		    default:
				p=(BTree *)malloc(sizeof(BTree));
		     	p->data=ch;p->lchild=p->rchild=NULL;
		         	if (b==NULL)                 //还没有创建根结点
						b=p;
					else
						k==1?st[top]->lchild=p:st[top]->rchild=p;
		}
		ch=str[++i];
	}
}

/**
*查找结点,返回指向该节点的指针
*/
BTree *Find(BTree *b,ElemType x){
	BTree *p;
	if (b==NULL)
	     return NULL;
    if (b->data==x)
	     return b;
	p=Find(b->lchild,x);
		if (p==NULL) 
			return Find(b->rchild,x);
		return NULL;
}

/**
*求二叉树的深度
*/
int BTreeDepth(BTree *b){
   	int l,r;
   	if (b==NULL) 
		return 0; 	
    return 1+((l=BTreeDepth(b->lchild))>(r=BTreeDepth(b->rchild))?l:r);
}

/**
*用括号表示法输出二叉树
*/
void Display(BTree *b){
	if (b!=NULL){
		printf("%c",b->data);
		if (b->lchild!=NULL || b->rchild!=NULL){
			printf("(");
			Display(b->lchild);
			if (b->rchild!=NULL) 
				printf(",");
			Display(b->rchild);
			printf(")");
		}
	}
}

/**
*先序遍历二叉树
*/
void Order(BTree *b){
	if(b!=NULL){
		printf("%c ",b->data);    //若中序遍历,此句放在倒数第二行;若后序,放最后一行
		Order(b->lchild);
		Order(b->rchild);
	}
}

/**先序遍历二叉树(非递归)
*这里用一个栈来存储父节点
*例如:A(B(D(,G)),C(E,F)),操作过程依次是:
*      A进栈(循环之前),top=0;A出栈,C、B入栈,top=1;B出栈,D入栈,top=1;
*      D出栈,G入栈,top=1;G出栈,top=0;C出栈,F、E入栈,top=1;
*      E出栈,top=0;F出栈,top=-1;
*/
void Order1(BTree *b){
	BTree *st[MaxSize]; int top=-1; 
	BTree *p=NULL;
	if(b!=NULL){
		top++;st[top]=b;
	}
	while(top!=-1){
		p=st[top];top--;
		if(p->rchild!=NULL){
			st[++top]=p->rchild;
		}
		if(p->lchild!=NULL){
			st[++top]=p->lchild;
		}
		printf("%c ",p->data);
	}
}

void InOrder(BTree *b)
{
	BTree *St[MaxSize],*p;
	int top=-1;
	if (b!=NULL)
	{
		p=b;
		while (top>-1 || p!=NULL)
		{
			while (p!=NULL)
			{
				top++;
				St[top]=p;
				p=p->lchild;
			}
			if (top>-1)
			{
				p=St[top];
				top--;
				printf("%c ",p->data);
				p=p->rchild;
			}
		}
		printf("\n");
	}
}

void PostOrder(BTree *b)
{
	BTree *St[MaxSize];
	BTree *p;
	int flag,top=-1;						//栈指针置初值
	if (b!=NULL)
	{
		do
		{
			while (b!=NULL)					//将t的所有左结点入栈
			{
				top++;
				St[top]=b;
				b=b->lchild;
			}
			p=NULL;							//p指向当前结点的前一个已访问的结点
			flag=1;	
			while (top!=-1 && flag)
			{
				b=St[top];					//取出当前的栈顶元素
				if (b->rchild==p)			//右子树不存在或已被访问,访问之
				{
					printf("%c ",b->data);	//访问*b结点
					top--;
					p=b;					//p指向则被访问的结点
				}
				else
				{
					b=b->rchild;			//t指向右子树
					flag=0;	
				}
			}
		} while (top!=-1);
		printf("\n");
	} 
}

void TravLevel(BTree *b)
{
	BTree *Qu[MaxSize];				//定义循环队列
	int front,rear;						//定义队首和队尾指针
	front=rear=0;						//置队列为空队列
    if (b!=NULL) 
		printf("%c ",b->data);
    rear++;								//结点指针进入队列
	Qu[rear]=b;
    while (rear!=front)					//队列不为空
    {
		front=(front+1)%MaxSize;
		b=Qu[front];					//队头出队列
		if (b->lchild!=NULL)			//输出左孩子,并入队列
		{
			printf("%c ",b->lchild->data);
			rear=(rear+1)%MaxSize;
			Qu[rear]=b->lchild;
		}
		if (b->rchild!=NULL)			//输出右孩子,并入队列
		{
			printf("%c ",b->rchild->data);
			rear=(rear+1)%MaxSize;
			Qu[rear]=b->rchild;
		}
	} 
	printf("\n");
}

void main()
{
	BTree *b;
	CreateBTree(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))"); 
	printf("       二叉树:");Display(b);
	printf("\n\n");
	printf(" 层次遍历序列:");
	TravLevel(b);printf("\n");
	printf(" 先序遍历序列:\n");
	printf("     递归算法:");Order(b);printf("\n");
	printf("   非递归算法:");Order1(b);printf("\n\n");
	printf(" 中序遍历序列:\n");
	printf("   非递归算法:");InOrder(b);printf("\n");
	printf(" 后序遍历序列:\n");
	printf("   非递归算法:");PostOrder(b);printf("\n");
	printf("     树的深度:");
	int d=BTreeDepth(b);printf("%d\n",d);
}

 运行结果:

       二叉树:A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))

 层次遍历序列:A B C D E F G H I J K L M N

 先序遍历序列:
     递归算法:A B D E H J K L M N C F G I
   非递归算法:A B D E H J K L M N C F G I

 中序遍历序列:
   非递归算法:D B J H L K M N E A F C G I

 后序遍历序列:
   非递归算法:D J L N M K H E B F I G C A

     树的深度:7

 

分享到:
评论

相关推荐

    二叉树深度_二叉树查询_二叉树深度_

    二叉树是一种在计算机科学中广泛应用的数据结构,它由节点(也称为结点)组成,每个节点最多有两个子节点,通常称为左子节点和右子节点。二叉树的深度是指从根节点到最远叶节点的最长路径上边的数目,即树的最大层数...

    二叉树演示 实现二叉树图形显示

    二叉树是一种特殊的树结构,每个节点最多只有两个子节点,通常分为左子节点和右子节点。在计算机科学中,二叉树被广泛应用于数据的组织和操作,如搜索、排序、文件系统等。本例子关注的是如何实现二叉树的图形显示,...

    根据后序二叉树序列构造二叉树_扩展二叉树

    在计算机科学领域,二叉树是一种基础的数据结构,它由结点构成,每个结点最多有两个子节点,分别称为左子节点和右子节点。在众多的二叉树操作中,根据后序遍历序列(也称为后序序列)来构造二叉树是一项常见的任务。...

    二叉树建立 二叉树基本算法的实现

    (2)先序、中序、后序遍历二叉树:递归算法。 (3)中序遍历二叉树:非递归算法(最好也能实现先序,后序非递归算法)。 (4)求二叉树的高度 。 (5)求二叉树的叶子个数。 (6)对于树中每一个元素值为x的结点...

    第六章 树和二叉树作业及答案(100分).docx

    - **答案解析**:如果一棵二叉树的中序遍历序列和后序遍历序列正好相反,那么该二叉树一定是任一结点都没有左孩子的二叉树。 #### 5. 二叉树的结点数范围 - **答案解析**:深度为k的二叉树最多有\(2^k - 1\)个结点...

    将满二叉树转化为求和二叉树_二叉树_

    在IT领域,特别是数据结构和算法的学习中,二叉树是一种重要的抽象数据类型。满二叉树是一种特殊的二叉树,其中每一层都是完全填充的,除了可能的最后一层,且最后一层的所有节点都尽可能地向左靠拢。而将满二叉树...

Global site tag (gtag.js) - Google Analytics