前言:
本篇文章仅给出关于二叉树的部分代码,若想深入了解二叉树请查看我的其他文章
因为本次实验二叉树考察的内容太多了,所以我把它拆分成了三个部分,分别是建立,处理,遍历三个板块,三篇文章可以在我的博客或专栏中找到。
以下是链接
二叉树递归总头文件:
建立包含以下内容:
二叉树结构,二叉树的三种建立。
遍历包含以下内容:
按层次非递归遍历、先序非递归、先中后序递归遍历二叉树的链表结构
处理包含以下内容:
求二叉树的高度、叶节点数、单分支节点数、双分支节点数,交换左右子树
目录
遍历时用到的打印函数:
这个打印函数会作为一个函数指针出现在遍历函数中,作为遍历的输出手段
Status print(TElemType e) {
//打印方式
printf("%c ", e);
return OK;
}
二叉树的递归遍历:
先序遍历:
Status TraverseBiTree_Pre(BiTree T, Status(*print)(TElemType)) {
//先序遍历二叉树
if(T) {
if(print(T->data)) {
if(TraverseBiTree_Pre(T->lchild, print)) {
if(TraverseBiTree_Pre(T->rchild, print)) {
return OK;
}
}
}
return ERROR;
}
return OK;
}
中序遍历:
Status TraverseBiTree_In(BiTree T, Status(*print)(TElemType)) {
//中序遍历二叉树
if(T) {
if(TraverseBiTree_In(T->lchild, print)) {
if(print(T->data)) {
if(TraverseBiTree_In(T->rchild, print)) {
return OK;
}
}
}
return ERROR;
}
return OK;
}
后序遍历:
Status TraverseBiTree_Post(BiTree T, Status(*print)(TElemType)) {
//后序遍历二叉树
if(T) {
if(TraverseBiTree_In(T->lchild, print)) {
if(TraverseBiTree_In(T->rchild, print)) {
if(print(T->data)) {
return OK;
}
}
}
return ERROR;
}
return OK;
}
二叉树的特殊遍历:
按层次非递归遍历:
这里需要用到队列,队列的头文件我会附在文章末
typedef BiTree QElemType;
#include "ArrayQueue.h"
Status TraverseBiTree_Level(BiTree T, Status(*print)(TElemType)) {
//层序遍历二叉树
if(T) {
ArrayQueue Q;
InitQueue(&Q);
EnQueue(&Q, T);
while(!QueueEmpty(Q)) {
DeQueue(&Q, &T);
print(T->data);
if(T->lchild) {
EnQueue(&Q, T->lchild);
}
if(T->rchild) {
EnQueue(&Q, T->rchild);
}
}
}
return OK;
}
先序非递归遍历二叉树:
这里需要用到栈,栈的头文件我会附在文章末
typedef BiTree SElemType;
#include "Stack.h"
Status TraverseBiTree_NRPre(BiTree T, Status(*print)(TElemType)) {
//非递归先序遍历二叉树
if(T) {
SqStack S;
InitStack(&S);
while(T || !StackEmpty(S)) {
if(T) {
Push(&S, T);
print(T->data);
T = T->lchild;
} else {
Pop(&S, &T);
T = T->rchild;
}
}
}
return OK;
}
栈头文件:
#include <stdio.h> //头文件
#include <stdlib.h>
#include <malloc.h>
#include <conio.h>
#include <string.h>
#define TRUE 1 //函数结果状态码
#define FALSE 0
#define ERROR 0
#define OK 1
#define EQUAL 1
#define OVERFLOW -1
#define INFEASIBLE -2
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
#define LIST_INIT_SIZE 100 //顺序表存储空间的初始分配量
#define LISTINCREMENT 10 //顺序表存储空间的分配增量
typedef int Status; //Status 为函数返回值类型,其值为函数结果状态代码
typedef struct { //栈的顺序存储表示
SElemType *base; //栈构造之前和销毁之后,其值为NULL
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间
} SqStack;
Status InitStack(SqStack *); //栈初始化
Status DestroyStack(SqStack *); //销毁栈
Status StackEmpty(SqStack); //栈判空
Status GetTop(SqStack, SElemType *); //取栈顶元素
Status Push(SqStack *, SElemType); //入栈
Status Pop(SqStack *, SElemType *); //出栈
Status StackTraverse(SqStack); //遍历栈,输出每个数据元素
Status InitStack(SqStack *S) {
//构造一个空栈Ss
S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if(!S->base) {
//存储分配失败
exit(OVERFLOW);
}
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
return OK;
}//InitStack
Status GetTop(SqStack S, SElemType *e) {
//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
if(S.top == S.base) {
return ERROR;
}
*e = *(S.top - 1);
return OK;
}//GetTop
Status Push(SqStack *S, SElemType e) {
//插入元素e为新的栈顶元素
if(S->top - S->base >= S->stacksize) {
//栈满,追加存储空间
S->base = (SElemType *)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));
if(!S->base) {
//存储分配失败
exit(OVERFLOW);
}
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREMENT;
}
*S->top++ = e;
return OK;
}//Push
Status Pop(SqStack *S, SElemType *e) {
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROE
if(S->top == S->base) {
return ERROR;
}
*e = *(--S->top);
return OK;
}//Pop
Status DestoryStack(SqStack *S) {
//销毁栈S
if(S->base) {
free(S->base);
}
S->top = S->base = NULL;
return OK;
}//DestroyStack
//Status StackTraverse(SqStack S) {
// //遍历栈,输出每一个数据元素
// SElemType *p = S.base;
// int i = 0;
// if(S.base == S.top) {
// printf("Stack is Empty.\n");
// return OK;
// }
// while(p < S.top) {
// printf("[%d:%d,%d]", ++i, p->i, p->j);
// p++;
// }
// printf("\n");
// return OK;
//}//StackTraverse
Status StackEmpty(SqStack S) {
//栈判空
if(S.base == S.top) {
return OK;
}
return ERROR;
}
队列头文件:
//#inclue <conio.h>
//#include <stdio.h>
#include <stdlib.h>
#define TRUE 1 //函数结果状态码
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define INFEASIBLE -2
typedef int Status; //Status 为函数返回值类型,其值为函数结果状态代码
typedef struct {
QElemType *base; //初始化的动态分配存储空间
int front; //队头指针
int rear; //队尾指针
int length; //队列总长度
} ArrayQueue;
Status InitQueue(ArrayQueue *); //构造一个空队列Q
Status DestroyQueue(ArrayQueue *); //销毁队列Q,Q不再存在
Status ClearQueue(ArrayQueue *); //将Q清为空队列
Status QueueEmpty(ArrayQueue ); //若队列Q为空,则返回TRUE,否则返回FALSE
int QueueLength(ArrayQueue ); //返回Q的元素个数,即为队列的长度
Status GetHead(ArrayQueue, QElemType *); //若队列不为空,则用e返回Q的队头元素,并返回OK;头则返回ERROR
Status EnQueue(ArrayQueue *, QElemType); //插入元素e为Q的新的队尾元素
Status DeQueue(ArrayQueue *, QElemType *); //若队列不为空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR;
//Status QueueTraverse(ArrayQueue, visit()); //从队头到队尾依次对队列Q中的每一个元素调用visit()。一旦visit失败,则操作失败;
Status InitQueue(ArrayQueue *Q) {
//构造一个空队列Q
Q->length = 100;
Q->base = (QElemType *)malloc(Q->length * sizeof(QElemType));
if(!Q->base) {
exit(OVERFLOW);
}
Q->front = Q->rear = 0;
return OK;
}
Status DestroyQueue(ArrayQueue *Q) {
//销毁队列Q,Q不再存在
free(Q->base);
return OK;
}
Status QueueEmpty(ArrayQueue Q) {
//若队列Q为空,则返回TRUE,否则返回FALSE
if(Q.front == Q.rear) {
return TRUE;
}
return FALSE;
}
int QueueLength(ArrayQueue Q) {
//返回Q的元素个数,即为队列的长度
return Q.rear - Q.front;
}
Status GetHead(ArrayQueue Q, QElemType *e) {
//若队列不为空,则用e返回Q的队头元素,并返回OK;头则返回ERROR
if(Q.front == Q.rear) {
return ERROR;
}
*e = Q.base[Q.front];
return OK;
}
Status EnQueue(ArrayQueue *Q, QElemType e) {
//插入元素e为Q的新的队尾元素
if(Q->rear == Q->length - 1) {
//队列满
Q->length += 100;
Q->base = (QElemType *)realloc(Q->base, Q->length * sizeof(QElemType));
}
Q->base[Q->rear] = e;
Q->rear++;
return OK;
}
Status DeQueue(ArrayQueue *Q, QElemType *e) {
//若队列不为空,则删除Q的队头元素,用e返回其值,并返回OK;
//否则返回ERROR;
if(Q->front == Q->rear) {
return ERROR;
}
*e = Q->base[Q->front];
Q->front++;
return OK;
}