实验8 二叉树的前 中 后序递归遍历 前序的非递归遍历 求深度
程序员文章站
2022-05-06 22:45:23
...
在这里插入图片描述
#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仍然是空的.
第二个 在入栈的时候 应该是对栈内容赋值, 而不是修改指针赋值
下一篇: 给定值,寻找二叉树中满足的所有路径