欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

实验8 二叉树的前 中 后序递归遍历 前序的非递归遍历 求深度

程序员文章站 2022-05-06 22:45:23
...

在这里插入图片描述
实验8 二叉树的前 中 后序递归遍历 前序的非递归遍历 求深度

#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:在写代码的过程中有两个很严重的错误

第一个 关于二级指针

实验8 二叉树的前 中 后序递归遍历 前序的非递归遍历 求深度

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

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

实验8 二叉树的前 中 后序递归遍历 前序的非递归遍历 求深度

相关标签: 二叉树的操作