二叉树的构建与层次遍历实现

// BinaryTree.cpp : 定义控制台应用程序的入口点。
//

#include "stdio.h"
#include "string.h"
#include "malloc.h"

int ntotal = 0,nleaf = 0;//ntotal表示总共节点,nleaf表示叶子节点

#define N 50

struct Node{
	char info;
	struct Node *parent;
	struct Node *lchild;
	struct Node *rchild;
};

typedef struct Node * PNode,BiNode;

struct Stack{
	char *pre;
	char *in;
	int n;
	PNode parent; 
};
typedef struct _QNode//把二叉树树转化为链表形式存储
{
	BiNode* data;
	struct _QNode* next;
}QNode;

typedef struct _queue//队列结构
{
	QNode* front;
	QNode* rear;
}Queue;

void InitQueue(Queue* q)//初始化队列
{
  q->front = q->rear = (QNode*)malloc(sizeof(QNode));
  q->front->next = NULL;
}

bool isQueueEmpty(Queue* q)//判断队列是否为空
{
  if(q->front == q->rear) 
   return true;
  else
   return false;
}
void EnQueue(Queue* q, BiNode* data)//向队列的末尾增加一个元素
{
  QNode* pNode;
  pNode = (QNode*)malloc(sizeof(QNode));
  pNode->data = data;
  pNode->next = NULL;
  q->rear->next = pNode;//接入队列的末尾
  q->rear = pNode;//把队列的尾指针指向新添加的节点
}
BiNode* DeQueue(Queue* q)//删除队列中的一个节点
{
  QNode* pNode;
  BiNode* pData;
  //assert(q->front != q->rear);
  pNode = q->front->next;
  q->front->next = pNode->next;
  if(q->rear == pNode)
  {
   q->rear = q->front;
  }
  pData = pNode->data;
  free(pNode);
  return pData;
}
void DestroyQueue(Queue* q)//销毁整个队列
{
  while(NULL != q->front)
  {
	  q->rear = q->front->next;
	  free(q->front);
	  q->front = q->rear;
  }
}

//二叉树的层次遍历,使用链队列实现
void LayerOrderTraverse(BiNode* T)
{
  Queue q;
  if(NULL == T) 
	  return;  
  InitQueue(&q);
  EnQueue(&q,T);
  while(!isQueueEmpty(&q))
  {
	   T = DeQueue(&q);
	   printf("%c ",T->info);
	   if(T->lchild)
		   EnQueue(&q,T->lchild);
	   if(T->rchild)
		   EnQueue(&q,T->rchild);
  }
  DestroyQueue(&q);  
}
int myIndex(char seq[],char c)
{
	 int i;
	 for(i = 0;seq[i] != '/0' ;i ++)
	 {
		  if(seq[i] == c)
		  {
			  return i;
		  }
	 }
	 return -1;
}
PNode  CreateTree(char pre[],char in[],int n,PNode parent)
{
	 PNode p,head = NULL;
	 struct Stack S[N],t;
	 int i,top = 0,done = 0;

	 while(!done)
	 {
		  while(n != 0)
		  {
			   i = myIndex(in,pre[0]);
			   p = (PNode)malloc(sizeof(struct Node));
			   p->info = pre[0];
			   p->parent = parent;
			   p->lchild = NULL;
			   p->rchild = NULL;

			   if(parent == NULL)
			   {
					head = p;
			   }
			   else
			   {
					parent->lchild = p;
			   }

			   if(n - i - 1 != 0)
			   {
					t.pre = pre + i + 1;
					t.in = in + i + 1;
					t.n = n - i - 1;
					t.parent = p;
					S[++top] = t;
			   }
			   pre = pre + 1;
			   n = i;
			   parent = p;
		  }

		  if(top != 0)
		  {
			   t = S[top--];//当初把这个地方赋值弄反了,导致结果错误!!
			   pre = t.pre;
			   in = t.in;
			   n = t.n;
			   parent = t.parent;

			   i = myIndex(in,pre[0]);
			   p = (PNode)malloc(sizeof(struct Node));
			   p->info = pre[0];
			   p->parent = parent;
			   p->lchild = NULL;
			   p->rchild = NULL;

			   if(parent == NULL)
			   {
					head = p;
			   }
			   else
			   {
					parent->rchild = p;
			   }

			   if(n - i - 1 != 0)
			   {
					t.pre = pre + i + 1;
					t.in = in + i + 1;
					t.n = n - i - 1;
					t.parent = p;
					S[++top] = t;	
			   }
			   pre = pre + 1;
			   n = i;
			   parent = p;

		  }
		  else
		  {
			 done = 1;
		  }
	}

 return head;
}

void pre_order(PNode root)
{
	 if(root != NULL)//必不可少的条件,递归的出口
	 {
	  printf("%2c",root->info);
	  pre_order(root->lchild);
	  pre_order(root->rchild);
  
	 }
}
void in_order(PNode root)
{
	 if(root != NULL)//必不可少的条件,递归的出口
	 {
	  in_order(root->lchild);
	  printf("%2c",root->info);
	  in_order(root->rchild);  
	 }
}

void later_order(PNode root)
{
	 if(root != NULL)//必不可少的条件,递归的出口
	 {
	  later_order(root->lchild);
	  later_order(root->rchild);
	  printf("%2c",root->info);
	 }
}

int TreeDepth(PNode root)
{
	 int nLeft, nRight;
	 if(root == NULL)//必不可少的条件,递归的出口
		 return 0;	
	 nLeft = TreeDepth(root->lchild);
	 nRight = TreeDepth(root->rchild);
	 return (nLeft > nRight) ? (nLeft + 1):(nRight + 1);
}

int totalnode(PNode root)
{
	 if(root != NULL)//必不可少的条件,递归的出口
	 {
		 ntotal ++;
		 totalnode(root->lchild);
		 totalnode(root->rchild);
	 }
	 return ntotal;
}

int leafnode(PNode root)
{
	 if(root != NULL)//必不可少的条件,递归的出口
	 {
		  if((root->lchild == NULL) && (root->rchild == NULL) )
		  {
			  nleaf ++;
		  }
		  leafnode(root->lchild);
		  leafnode(root->rchild);
	 }
	 return nleaf;
}

int main()
{
	 PNode root;
	// char pre[N],in[N];//分别表示前序序列和中序序列
	 int depth,ntotalnode,nleafnode;
	 //printf("请输入前序遍历:");
	 //scanf("%s",pre);
	 char* pre = "abdecfg";
	 //printf("请输入中序遍历:");
	 //scanf("%s",in);
	 char *in = "dbeacgf";

	 root = CreateTree(pre,in,strlen(pre),NULL);

	 printf("\n前序遍历为:");
	 pre_order(root);

	 printf("\n中序遍历为:");
	 in_order(root);

	 printf("\n后序遍历为:");
	 later_order(root);

	 depth = TreeDepth(root);
	 printf("\n树的深度为:%d\n",depth);
 
	 ntotalnode = totalnode(root);
	 printf("总共节点为:%d\n",ntotalnode);
 
	 nleafnode = leafnode(root);
	 printf("总共叶子节点为:%d\n",nleafnode);

	 printf("\n二叉树的层次遍历为:");
	 LayerOrderTraverse(root);

	 printf("\n\n");
	 return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值