//#include "Header.h"
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> //exit 函数需要
#include <malloc.h>
#define MAXSIZE 20 //队列长度
#define NOINFO -1 //输入-1 结点为空
//定义二叉树
typedef struct node
{
int data;
struct node* L;
struct node* R;
}Tnode, * BTree;
//定义队列结点
typedef struct QNode {
BTree data;
struct QNode* next;
}Qnode, * PQnode;
//定义队列
typedef struct Qnode {
PQnode front;//队头指针
PQnode rear;//队尾指针
int size;
}LinkQuene, * Q;
//链表队列函数原型
void Initqueue(Q queue);
bool enqueue(Q queue, BTree BT); //入队
BTree dequeue(Q queue); //出队
bool(QueueEmpty(queue));
//bool is_full(Q queue);
//void show_queue(Q queue);
//二叉树操作函数原型
BTree CreatBintree(void);
void LevTraverse(BTree BT);
void PreTraverse(BTree BT); //先序遍历,先根
void InTraverse(BTree BT); //中序遍历,中根
void PostTraverse(BTree BT); //后序遍历
main() {
BTree BT;
BT = CreatBintree();
LevTraverse(BT);
PreTraverse(BT); //先序遍历
InTraverse( BT); //中序遍历
PostTraverse( BT); //后序遍历
LevTraverse( BT);
}
BTree CreatBintree(void) {
int in; //二叉树结点,以int 为例
BTree BT; //二叉树结点,指针变量
BTree T; // 出队的结点,指针
LinkQuene Cr_queue; //定义队列结构变量
LinkQuene* Q = &Cr_queue; //取地址,用指针后面用Q传递方便
Initqueue(Q); //初始化队列
scanf_s("%d", &in);
if (in != NOINFO) {
//树根结点初始化
BT = (BTree)malloc(sizeof(Tnode)); //动态分配二叉树结点内存,返回指针类型,赋值给BT
BT->data = in;
BT->L = BT->R = NULL; //先把左右指针置空
enqueue(Q, BT); ////根结点放入队列
}
else
return NULL; //如果第一个输入数据为 -1 ,二叉树为空,
// 遍历时的很多地方判断条件就是根据这个空指针,创建树时,需输入多个-1
while (!QueueEmpty(Q)) { //循环出队,出完了条件就非
T = dequeue(Q);
scanf_s("%d", &in);
if (in == NOINFO) T->L = NULL; //如果输入-1 ,左儿子没有,下面的if就不会申请内存
else
{
T->L = (BTree)malloc(sizeof(struct node));
T->L->data = in;
T->L->L = T->L->R = NULL;
enqueue(Q, T->L);
}
scanf_s("%d", &in);
if (in == NOINFO) T->R = NULL; //如果输入-1 ,右儿子没有
else
{
T->R = (BTree)malloc(sizeof(struct node));
T->R->data = in;
T->R->L = T->R->R = NULL;
enqueue(Q, T->R);
}
}
return BT;
}
void LevTraverse(BTree BT) {
BTree T;
LinkQuene Lev_queue; //定义队列
LinkQuene* Q = &Lev_queue;
if (!BT)
printf("BTree is empty!");
if (BT) {
Initqueue(Q); //队列初始化
enqueue(Q, BT); //入队
while (!QueueEmpty(Q)) {
T = dequeue(Q); //出队
printf("%d ", T->data);
if (T->L) enqueue(Q, T->L); //如果有左儿子,左儿子入队
if (T->R) enqueue(Q, T->R);
}
}
}
void PreTraverse(BTree BT) {
if (BT)
printf("BTree is empty!");
else {
if (BT) {
printf("%d", BT->data); //先输出,然后不断向左递归
PreTraverse(BT->L);
PreTraverse(BT->R);
}
}
}
void PostTraverse(BTree BT) {
if (BT)
printf("BTree is empty!");
else {
if (BT) {
PreTraverse(BT->L);
PreTraverse(BT->R);
printf("%d", BT->data);
}
}
}
void InTraverse(BTree BT) {
if (BT)
printf("BTree is empty!");
else {
if (BT) {
PreTraverse(BT->L);
printf("%d", BT->data);
PreTraverse(BT->R);
}
}
}
void Initqueue(Q queue) {
queue->front = NULL;
queue->rear = NULL;
queue->size = 0;
}
bool enqueue(Q queue, const BTree BT) {
PQnode node; //创建队列结点
node = (PQnode)malloc(sizeof(LinkQuene)); //申请队列结点内存
if (node == NULL)
exit(-1);
node->data = BT; //二叉树结点 放入队列结点,都不是指针
node->next = NULL;
if (QueueEmpty(queue)) //初始状态
{
queue->front = node;
queue->rear = node;
}
else
{
queue->rear->next = node; //后面结点的连上
queue->rear = node; //rear 指向新结点
}
++queue->size; //可以设置队列长度
return 1;
}
BTree dequeue(Q queue) { //出队,返回出点的树结点
BTree BT;
PQnode tmp;
if (QueueEmpty(queue))
{
return 0;
}
tmp = queue->front; // TEMP 指针指向队头
BT = queue->front->data; //队头数据给BT
queue->front = queue->front->next; //front指针后移
free(tmp); //释放内存
--queue->size;
return BT;
}
bool(QueueEmpty(Q queue)) {
if (queue->size == 0)
return 1;
else
return 0;
}
//下面的函数就不写了
//bool is_full(Q queue) {
//}
//void show_queue(Q queue) {
//}