本次模拟二叉树实现的功能
1.按要求创建一棵树
2.计算树节点,树叶子节点的个数
3.输出树中第n层的节点个数
4.关于树前序,中序,后序的递归遍历
5.树的层序遍历
6.判断树是否为完全二叉树
7.树的前序,中序,后序的非递归遍历
其中二叉树非递归遍历具体实现的讲解,可参考下篇博客: 二叉树的非递归遍历
注意:
二叉树的递归遍历实现:直接按遍历顺序递归调用
二叉树的层序遍历实现:可以借用队列结构来实现
二叉树的非递归遍历实现:可以借用栈结构来实现前序遍历: 根 – 左 – 右
中序遍历: 左 – 根 – 右
后序遍历: 左 – 右 – 根
代码示例如下:
小编提示:作者用的编译器是VS,若编译器不同,可以将代码中的#define _CRT_SECURE_NO_WARNINGS 1
和 system("pause");
注释掉,不然直接运行代码的话可能会报错哦~
Tree.h – 头文件
// #define _CRT_SECURE_NO_WARNINGS 1
#ifndef __TREE_H__ //宏的使用,主要防止头文件的重复包含和编译
#define __TREE_H__
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
typedef char BTDataType;
typedef struct BinaryTreeNode //树节点定义
{
BTDataType _data;
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
}BTNode;
//创建树
BTNode *BinaryTreeCreate(BTDataType*a, int*pi);
//销毁树
void BinaryTreeDestory(BTNode* root);
//树的结点
int BinaryTreeSize(BTNode* root);
//树的叶子结点
int BinaryTreeLeafSize(BTNode* root);
//树某一层的结点
int BinaryTreeLevelkSize(BTNode* root, int k);
//找到某个元素
BTNode *BinaryTreeFind(BTNode* root, BTDataType x);
//遍历
void BinaryTreePrevOrder(BTNode* root); //前序
void BinaryTreeInOrder(BTNode* root); //中序
void BinaryTreePostOrder(BTNode* root); //后序
//层序遍历
void BinaryTreeLevelOrder(BTNode* root);
//判断是否完全二叉树
int BinaryTreeComplete(BTNode* root);
//非递归遍历
void BinaryPrevOrder(BTNode* root); //前序
void BinaryInOrder(BTNode* root); //中序
void BinaryPostOrder(BTNode* root); //后序
//测试类
void Test();
//队列定义以及操作声明
typedef BTNode* QDataType;
typedef struct QueueNode
{
QDataType _data;
struct QueueNode* _next;
}QNode; //定义队列节点结构
typedef struct Queue
{
QNode* _head;
QNode* _tail;
}Qu; //定义队列指针结构
void QueueInit(Qu* pq);
void QueueDestory(Qu* pq);
void QueuePrint(Qu* pq);
QNode* BuyQueueNode(QDataType x);
void QueuePush(Qu* pq, QDataType x);
void QueuePop(Qu* pq);
QDataType QueueFront(Qu* pq);
QDataType QueueBack(Qu* pq);
int QueueEmpty(Qu* pq);
int QueueSize(Qu* pq);
void TestQueue();
//栈定义以及操作声明
typedef BTNode* STDataType;
typedef struct Stack
{
STDataType* _a;
int _top;
int _capacity;
}Stack; //定义栈结构
void StackInit(Stack* ps);
void StackDestory(Stack* ps);
void StackPush(Stack *ps, STDataType x);
void StackPop(Stack* ps);
STDataType StackTop(Stack* ps);
int StackEmpty(Stack* ps);
int StackSize(Stack* ps);
void StackPrint(Stack* ps);
void TestStack();
#endif //__TREE_H__
Tree.c – 树的操作
// #define _CRT_SECURE_NO_WARNINGS 1
#include "Tree.h"
BTNode *BinaryTreeCreate(BTDataType*a, int* pi) //创建树
{
if (a[*pi] == '#')
{
(*pi)++;
return NULL;
}
BTNode* root = (BTNode*)malloc(sizeof(BTNode));
root->_left = root->_right = NULL;
root->_data = a[*pi];
(*pi)++;
root->_left = BinaryTreeCreate(a, pi);
root->_right = BinaryTreeCreate(a, pi);
return root;
}
void BinaryTreeDestory(BTNode* root) //销毁树
{
if (root)
{
BinaryTreeDestory(root->_left);
BinaryTreeDestory(root->_right);
free(root);
root = NULL;
}
}
int BinaryTreeSize(BTNode* root) //统计树节点个数
{
if (root == NULL)
return 0;
return 1 + BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right);
}
int BinaryTreeLeafSize(BTNode* root) //统计树的叶子节点个数
{
if (root == NULL)
return 0;
else
{
if ((root->_left == NULL) && (root->_right == NULL))
return 1;
else
return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}
}
int BinaryTreeLevelkSize(BTNode* root, int k) //递归--统计树中第k层的节点个数
{
if (root == NULL) return 0;
if (k==1)
return 1;
return BinaryTreeLevelkSize(root->_left,k-1) + BinaryTreeLevelkSize(root->_right,k-1);
}
BTNode *BinaryTreeFind(BTNode* root, BTDataType x) //找到某个树节点
{
BTNode* ret;
if (root == NULL)
return NULL;
if (root->_data == x)
return root;
ret = BinaryTreeFind(root->_left, x);
{
if (ret)
return ret;
ret = BinaryTreeFind(root->_right, x);
if (ret)
return ret;
}
return NULL;
}
void BinaryTreePrevOrder(BTNode* root) //递归--前序遍历
{
if (root == NULL)
return;
printf("%c ", root->_data);
BinaryTreePrevOrder(root->_left);
BinaryTreePrevOrder(root->_right);
}
void BinaryTreeInOrder(BTNode* root) //递归--中序遍历
{
if (root == NULL)
return;
BinaryTreeInOrder(root->_left);
printf("%c ", root->_data);
BinaryTreeInOrder(root->_right);
}
void BinaryTreePostOrder(BTNode* root) //递归--后序遍历
{
if (root == NULL)
return;
BinaryTreePostOrder(root->_left);
BinaryTreePostOrder(root->_right);
printf("%c ", root->_data);
}
void BinaryTreeLevelOrder(BTNode* root) //层序遍历
{
Qu q;
QueueInit(&q);
if (root != NULL)
{
QueuePush(&q, root);
while (QueueEmpty(&q) != 0)
{
BTNode* front = QueueFront(&q);
printf("%c ", front->_data);
QueuePop(&q);
if (front->_left)
QueuePush(&q, front->_left);
if (front->_right)
QueuePush(&q, front->_right);
}
}
}
int BinaryTreeComplete(BTNode* root) //判断树是否是完全二叉树
{
Qu q;
QueueInit(&q);
if (root != NULL)
{
QueuePush(&q, root);
while (QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front == NULL)
break;
QueuePush(&q, front->_left);
QueuePush(&q, front->_right);
}
while (QueueEmpty(&q) )
{
BTNode* front = QueueFront(&q);
if (front != NULL)
{
QueueDestory(&q);
return 0;
}
QueuePop(&q);
}
return 1;
}
return 0;
}
void BinaryPrevOrder(BTNode* root) //非递归--前序遍历
{
Stack st;
StackInit(&st);
BTNode* cur = root;
while (StackEmpty(&st) != 0 || cur != NULL)
{
while (cur != NULL)
{
printf("%c ", cur->_data);
StackPush(&st, cur);
cur = cur->_left;
}
BTNode* top = StackTop(&st);
StackPop(&st);
cur=top->_right;
}
}
void BinaryInOrder(BTNode* root) //非递归--中序遍历
{
Stack st;
StackInit(&st);
BTNode* cur = root;
while (StackEmpty(&st) != 0 || cur != NULL)
{
while (cur != NULL)
{
StackPush(&st, cur);
cur = cur->_left;
}
BTNode* top = StackTop(&st);
printf("%c ", top->_data);
StackPop(&st);
cur = top->_right;
}
}
void BinaryPostOrder(BTNode* root) //非递归--后序遍历
{
BTNode* cur = root;
BTNode* prev = NULL;
Stack st;
StackInit(&st);
while (cur || StackEmpty(&st) != 0)
{
while (cur != NULL)
{
StackPush(&st, cur);
cur = cur->_left;
}
BTNode* top = StackTop(&st);
if (top->_right == NULL || top->_right == prev)
{
StackPop(&st);
printf("%c ", top->_data);
prev = top;
}
else cur=top->_right;
}
}
void Test()
{
char a[20] = "ABD##E#H##CF##G##";
//int sz = (sizeof(a) / sizeof(a[0]));
int pi = 0;
int i = 0;
BTNode* root = BinaryTreeCreate(a, &pi);
printf("树创建成功!\n");
printf("树点的个数是: ");
printf("%d\n", BinaryTreeSize(root));
printf("树叶子结点的个数是: ");
printf("%d\n", BinaryTreeLeafSize(root));
printf("第3层结点的个数是: ");
printf("%d\n", BinaryTreeLevelkSize(root, 3));
printf("树前序遍历的结果是: ");
BinaryTreePrevOrder(root);
printf("\n");
printf("树中序遍历的结果是: ");
BinaryTreeInOrder(root);
printf("\n");
printf("树后序遍历的结果是: ");
BinaryTreePostOrder(root);
printf("\n");
printf("树层序遍历的结果是: ");
BinaryTreeLevelOrder(root);
printf("\n");
i=BinaryTreeComplete(root);
if (i == 1) printf("此树是完全二叉树。\n ");
else printf("此树非完全二叉树。\n ");
printf("\n\n\n 下面是树的非递归遍历!\n");
printf("树前序遍历的结果是: ");
BinaryPrevOrder(root);
printf("\n");
printf("树中序遍历的结果是: ");
BinaryInOrder(root);
printf("\n");
printf("树后序遍历的结果是: ");
BinaryPostOrder(root);
printf("\n");
BinaryTreeDestory(root);
printf("销毁成功!\n");
}
Queue.c – 队列的操作(辅助层序遍历)
// #define _CRT_SECURE_NO_WARNINGS 1
#include "Tree.h"
void QueueInit(Qu* pq) //队列初始化
{
QDataType x = 0;
assert(pq);
pq->_head = BuyQueueNode(x);
pq->_tail = pq->_head;
}
void QueueDestory(Qu* pq) //队列销毁
{
QNode* cur = pq->_head->_next; //节点指针指向队列头节点
while (cur != NULL)
{
QNode* next = cur->_next; //记录下一个节点
free(cur); //释放当前节点
cur = next; //指针指向下一个节点
}
}
QNode* BuyQueueNode(QDataType x) //新增队列节点
{
QNode* newNode = (QNode*)malloc(sizeof(QNode)); //新增一个节点
newNode->_data = x; //为节点赋值
newNode->_next = NULL; //节点指针初始化
return newNode; //返回当前新增的节点
}
void QueuePush(Qu* pq, QDataType x) //指定值进入队列
{
QNode* newnode = BuyQueueNode(x); //新增指定值的节点
pq->_tail->_next = newnode; //连接新节点
pq->_tail = newnode; //队列尾指针后移
}
void QueuePop(Qu* pq) //出队列
{
assert(pq);
QNode* cur = pq->_head->_next; //结点指针
if (cur == NULL) //无节点直接返回
{
return;
}
if (cur == pq->_tail) //只有一个节点,尾节点前移
{
pq->_tail = pq->_head;
}
pq->_head->_next = cur->_next; //将头节点后移
free(cur); //节点释放
}
QDataType QueueFront(Qu* pq) //返回队列头部的值
{
QNode* cur = pq->_head->_next;
assert(pq);
return cur->_data;
}
QDataType QueueBack(Qu*pq) //队列尾部的值
{
assert(pq);
return pq->_tail->_data;
}
int QueueEmpty(Qu* pq) //队列判空
{
QNode* cur = pq->_head->_next;
if (cur == NULL)
return 0;
else return 1;
}
int QueueSize(Qu* pq) //队列节点总数
{
int count = 0;
QNode* cur = pq->_head->_next;
if (cur == NULL)
return 0;
while (cur)
{
count++;
cur = cur->_next;
}
return count;
}
void QueuePrint(Qu* pq) //队列打印
{
QNode* cur = pq->_head->_next;
assert(pq);
while (cur != NULL)
{
printf("%d ", cur->_data);
cur = cur->_next;
}
printf("\n");
}
Stack.c – 栈的操作(辅助非递归遍历)
#define _CRT_SECURE_NO_WARNINGS 1
#include "Tree.h"
void StackInit(Stack* ps)
{
assert(ps);
ps->_a = NULL;
ps->_capacity = 0;
ps->_top = 0;
}
void StackDestory(Stack* ps)
{
assert(ps);
ps->_capacity = 0;
ps->_top = 0;
free(ps->_a);
ps->_a = NULL;
}
void StackPush(Stack *ps, STDataType x)
{
assert(ps);
if (ps->_top == ps->_capacity)
{
size_t newcapacity = (ps->_capacity == 0 ? 4 : ps->_capacity * 2);
ps->_a = (STDataType*)realloc(ps->_a, sizeof(STDataType)*newcapacity);
ps->_capacity = newcapacity;
}
ps->_a[ps->_top]= x;
ps->_top++;
}
void StackPop(Stack* ps)
{
assert(ps&&ps->_top>0);
ps->_top--;
}
STDataType StackTop(Stack* ps)
{
assert(ps&&ps->_top>0);
return ps->_a[ps->_top - 1];
}
int StackEmpty(Stack* ps)
{
assert(ps);
if (ps->_top == 0)
return 0;
else return 1;
}
int StackSize(Stack* ps)
{
assert(ps);
STDataType size = ps->_top;
return size;
}
void StackPrint(Stack* ps)
{
assert(ps);
while (StackEmpty(ps) != 0)
{
printf("%d ", StackTop(ps));
StackPop(ps);
}
printf("\n");
}
test.c – 主文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "Tree.h"
int main()
{
printf(" *******二叉树的实现******\n");
Test();
printf("\n");
printf("\n");
printf("\n");
// system("pause");
return 0;
}
运行结果如下: