二叉树的遍历

在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define TRUE 1
#define FALSE 0 
#define STACK_INIT_SIZE 1000 //栈的初始化最大存储量 
#define STACKINCREMENT 10//栈的增量 

typedef int  Status;
typedef char TElemType; 

struct BiTreeNode{//二叉树结构体 
	TElemType data;
	struct BiTreeNode *leftChild, *rightChild;
};
typedef struct BiTreeNode BiNode;

struct QNode{//队列结构体 
	BiNode *data;
	struct QNode *next;
};
typedef struct QNode Queue;

struct point{
	Queue *front;//队头指针 
	Queue *rear;//队尾指针 
};
typedef struct point Point;
/************栈结构体********************/
struct sstack{
	BiNode *base;//栈底指针 
	BiNode *top;//栈顶指针 
	int stacksize;//最大容量 
};
typedef struct sstack Stack;
/********************************/
void printMessage();
BiNode * createBiTree(BiNode **);//初始化二叉树, 创建空树 
Status preorderTraversal(BiNode *);//先序遍历
Status recursionInorderTraversal(BiNode *);// 递归中序遍历 
Status inorderTraversal(BiNode *);//非递归中序遍历
Status postorderTraversal(BiNode *);//后序遍历 
Status sequenceTraversal(BiNode *);//层序遍历
int getDeep(BiNode *);

Status initQueue(Point *);
Status emptyQueue(Point );//判断是否为空 
void enQueue(Point *, BiNode *);//入队 
Queue* deQueue(Point *); //出队 

Status initStack(Stack *);
Status emptyStack(Stack *);//判空 
void pop(Stack *, BiNode **);//出栈
void push(Stack *, BiNode *);//入栈 


int main()
{
	printMessage();
	BiNode *biTree = NULL;	
	int select = 0;
	printf("请选择:");
	
	while(select != 8) 
	{
		if(select < 1 || select > 8){
			printf("选择错误, 请重新选择!\n");
			scanf("%d",&select);
			continue;
		} 
		switch(select){
		case 1:
			{
				createBiTree(&biTree);
				break;
			}
		case 2:
			preorderTraversal(biTree);//前序遍历 
			putchar('\n');
			break;
		case 3:
			recursionInorderTraversal(biTree);//中序遍历
			putchar('\n'); 
			break;
		case 4:
			inorderTraversal(biTree);//非递归中序遍历二叉树 
			putchar('\n');
			break;
		case 5:
			postorderTraversal(biTree);//后序遍历 
			putchar('\n');
			break;
		case 6:
			sequenceTraversal(biTree);//层序遍历 
			putchar('\n');
			break;
		case 7:
			{
				int len = getDeep(biTree);
				printf("该二叉树的长度为:%d\n",len);
				break; 
			}
	} 
		printf("请选择:");
		scanf("%d",&select);
		system("cls");
		printMessage(); 
	}
	return 0; 
}
void printMessage()
{
	printf("1. 创建二叉树\n");
	printf("2. 先序遍历二叉树\n");
	printf("3. 中序遍历二叉树\n");
	printf("4. 中序\"非递归\"遍历二叉树\n");
	printf("5. 后序遍历二叉树\n");
	printf("6. 层序遍历二叉树\n");
	printf("7. 求二叉树的深度\n");
	printf("8. 退出\n");
}
BiNode * createBiTree(BiNode **biTree)
{
	char ch;
	printf("请输入字符:\n");
	getchar();
	ch = getchar();
	if(ch == '1') *biTree = NULL;
	else{
		*biTree = (BiNode*)malloc(sizeof(BiNode));
		(*biTree)->data = ch;//生成根结点
		createBiTree(&((*biTree)->leftChild));//构造左子树 
		createBiTree(&((*biTree)->rightChild)); //构造右子树
		return *biTree;  
	} 
}

Status preorderTraversal(BiNode *biTree)//先序遍历
{ 
	if(biTree){
		printf("%c ",biTree->data);
		preorderTraversal(biTree->leftChild);
		preorderTraversal(biTree->rightChild);
	}
	return TRUE;
} 
Status recursionInorderTraversal(BiNode *biTree)//递归中序遍历 
{
	if(biTree){
		recursionInorderTraversal(biTree->leftChild);
		printf("%c ",biTree->data);
		recursionInorderTraversal(biTree->rightChild);
	}
	return TRUE;
}
Status inorderTraversal(BiNode *biTree)//非递归中序遍历 
{
	Stack stack;//创建一个栈
	initStack(&stack);
	BiNode *temp = biTree;
	while (temp != NULL || emptyStack(&stack) != 0) {// 栈不空或树不空
          if (temp != NULL) {
               printf("%c ",temp->data);
               push(&stack, temp);  
			    temp = temp->leftChild;
			}  // 根指针进栈,遍历左子树
          else {    // 左子树访问完了,根指针退栈, 遍历右子树
            	 pop(&stack, &temp); 
                 temp = temp->rightChild;
           	}  
     }   
	return TRUE;
}
Status postorderTraversal(BiNode *biTree)//后序遍历
{
	if(biTree){
		postorderTraversal(biTree->leftChild);
		postorderTraversal(biTree->rightChild);
		printf("%c ",biTree->data);
	}
	return TRUE;
}
Status sequenceTraversal(BiNode *biTree)//层序遍历 
{
	Point point;
	point.front = NULL;
	point.rear = NULL; 
	initQueue(&point);//初始化队列 
	if(biTree != NULL){//如果节点不为空,则入队 
		enQueue(&point, biTree);
	} 
	while(emptyQueue(point)){//出队while循环 , 当队列不为空的时候while循环满足条件 
		Queue *temp = deQueue(&point);
		printf("%c ",temp->data->data);
		
		if(temp->data->leftChild != NULL)//如果左子树不为空 ,则入队 
			enQueue(&point, temp->data->leftChild);
		if(temp->data->rightChild != NULL)//如果右子树不为空, 则入队 
			enQueue(&point, temp->data->rightChild);
	}
} 
int getDeep(BiNode *biTree)
{
	if (biTree == NULL)
		return 0;
	int nLeft = getDeep(biTree->leftChild);
	int nRight = getDeep(biTree->rightChild);
	return (nLeft>nRight) ? (nLeft+1):(nRight+1);
}
Status initQueue(Point *point)
{
	point->front = (Queue*)malloc(sizeof(Queue));
	if(point->front == NULL)return FALSE; 
	point->rear = point->front;
	point->rear->next = NULL; 
	return TRUE; 
}
void enQueue(Point *point, BiNode *biTree)//入队 
{
	 point->rear->data = biTree;//给当前节点赋值 
	 Queue *newQueue = (Queue*)malloc(sizeof(Queue));//申请新节点 
	 newQueue->next = NULL; 
	 point->rear->next = newQueue;//将rear的值往后移,指向最新的队列节点 
	 point->rear = newQueue; 
}
Queue* deQueue(Point *point) //出队 
{
 	 Queue *temp = point->front;
	 point->front = point->front->next;
	 return temp; 
}
Status emptyQueue(Point point)
{
	if(point.front == point.rear)return FALSE;
	else return TRUE;//不为空 
}
Status initStack(Stack *stack)//初始化栈 
{
	stack->base = (BiNode *)malloc(sizeof(BiNode)*STACK_INIT_SIZE) ;
	if(!stack->base) return FALSE;//申请内存失败;
	stack->stacksize = STACK_INIT_SIZE;
	stack->top = stack->base;
	return TRUE;
 }

void pop(Stack *stack, BiNode **biNode)//出栈
{
	stack->top--;
	*biNode = stack->top;
}
void push(Stack *stack, BiNode *biNode)//入栈 
{
	*(stack->top) = *biNode;//**这里并没有考虑栈满的情况,**
	stack->top++;
}
Status emptyStack(Stack *stack)//判断栈是否为空 
{
	if(stack->base == stack->top)return FALSE;
	return TRUE;//TRUE说明栈不为空 
}

PS:在写代码的过程中有两个很严重的错误

第一个 关于二级指针

在这里插入图片描述

要修改指针的内容, 必须要用二级指针. 否则初始化后 biTree仍然是空的.

第二个 在入栈的时候 应该是对栈内容赋值, 而不是修改指针赋值

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值