一、BTree.h
#ifndef __BTree_h__
#define __BTree_h__
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <Windows.h>
typedef int BTDataType;
typedef struct BinaryTreeNode
{
struct BinaryTreeNode* _left; //左孩子
struct BinaryTreeNode* _right; //右孩子
BTDataType _data; //节点数据
}BTNode;
BTNode* BuyBTNode(BTDataType x);
BTNode* CreateBTree(BTDataType* a, size_t* pIndex, BTDataType invalid);
void BTreePrevOrder(BTNode* root);
void BTreeInOrder(BTNode* root);
void BTreePostOrder(BTNode* root);
void BTreeLevelOrder(BTNode* root);
size_t BTreeSize(BTNode* root);
size_t BTreeLeafSize(BTNode* root);
size_t BTreeKLevelSize(BTNode* root, size_t k);
size_t BTreeDepth(BTNode* root);
BTNode* BTreeFind(BTNode* root, BTDataType x);
int IsCompleteBTree(BTNode* root);
int IsCompleteBTree1(BTNode* root);
void BTreePrevOrderNonR(BTNode* root);
void BTreeInOrderNonR(BTNode* root);
void BTreePostOrderNonR(BTNode* root);
#endif __BTree_h__
二、Queue.h
#ifndef __Queue_h__
#define __Queue_h__
#include "BTree.h"
typedef BTNode* QDataType;
typedef struct QueueNode
{
QDataType _data;
struct QueueNode* _next;
}QueueNode;
typedef struct Queue
{
QueueNode* _head; //队头指针
QueueNode* _tail; //队尾指针
}Queue;
//初始化
void QueueInit(Queue* q)
{
assert(q);
q->_head = q->_tail = (QueueNode*)malloc(sizeof(QueueNode));
assert(q->_head&&q->_tail);
q->_head->_next = NULL;
}
//销毁
void QueueDestroy(Queue* q)
{
assert(q);
while (q->_head)
{
q->_tail = q->_head->_next;
free(q->_head);
q->_head = q->_tail;
}
}
//入队
void QueuePush(Queue* q, QDataType x)
{
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
assert(newnode);
newnode->_data = x;
newnode->_next = NULL;
q->_tail->_next = newnode;
q->_tail = newnode;
}
//出队
void QueuePop(Queue* q)
{
if (q->_head == q->_tail)
{
return;
}
QueueNode* next = q->_head->_next;
q->_head->_next = next->_next;
if (q->_tail == next)
{
q->_tail = q->_head;
}
free(next);
}
//获取队头元素
QDataType QueueFront(Queue* q)
{
if (q->_head == q->_tail)
{
return NULL;
}
else
{
return q->_head->_next->_data;
}
}
//判空
int QueueEmpty(Queue* q)
{
if (q->_head == q->_tail)
{
return 1;
}
return 0;
}
#endif __Queue_h__
三、stack.h
#ifndef __stack_h__
#define __stack_h__
#include "BTree.h"
#define Initsize 5 //初始存储空间
#define Increment 2 //每次增量
typedef BTNode* SDataType;
typedef struct Stack
{
SDataType* _array;
size_t _size; //有效数据个数
size_t _capacity; //容量
}Stack;
//初始化
void StackInit(Stack* s)
{
assert(s);
s->_size = 0;
s->_capacity = Initsize;
s->_array = (SDataType*)malloc(Initsize*sizeof(SDataType));
if (s->_array == NULL)
{
perror("StackInit");
return;
}
memset(s->_array, 0, s->_capacity * sizeof(SDataType));
}
//扩容
void CheckCapacity(Stack* s)
{
assert(s);
if (s->_size >= s->_capacity)
{
SDataType* ptr = (SDataType*)realloc(s->_array, (s->_capacity + Increment)*sizeof(SDataType));
if (ptr == NULL)
{
perror("CheckCapacity");
}
else
{
s->_array = ptr;
s->_capacity += Increment;
}
}
}
//入栈
void StackPush(Stack* s, SDataType x)
{
assert(s);
CheckCapacity(s);
s->_array[s->_size] = x;
s->_size++;
}
//出栈
void StackPop(Stack* s)
{
assert(s);
if (s->_size == 0)
{
return;
}
else
{
s->_size--;
}
}
//获取栈顶元素
SDataType StackTop(Stack* s)
{
assert(s);
if (s->_size == 0)
{
return NULL;
}
return s->_array[(s->_size) - 1];
}
//判空
int StackEmpty(Stack* s)
{
assert(s);
if (s->_size)
{
return 1;
}
else
{
return 0;
}
}
#endif __stack_h__
四、BTree.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "BTree.h"
#include "Queue.h"
#include "stack.h"
//创建节点
BTNode* BuyBTNode(BTDataType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
assert(node);
node->_data = x;
node->_left = NULL;
node->_right = NULL;
return node;
}
//创建二叉树
BTNode* CreateBTree(BTDataType* a, size_t* pIndex, BTDataType invalid) //
{
BTNode* root = NULL;
if (a[*pIndex] != invalid)
{
root = BuyBTNode(a[*pIndex]);
(*pIndex)++;
root->_left = CreateBTree(a, pIndex, invalid); //左递归
(*pIndex)++;
root->_right = CreateBTree(a, pIndex, invalid); //右递归
}
return root;
}
//先序遍历
void BTreePrevOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
printf("%d ", root->_data); //访问根
BTreePrevOrder(root->_left); //左递归
BTreePrevOrder(root->_right); //右递归
}
//中序遍历
void BTreeInOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
BTreeInOrder(root->_left); //左递归
printf("%d ", root->_data); //访问根
BTreeInOrder(root->_right); //右递归
}
//后序遍历
void BTreePostOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
BTreePostOrder(root->_left); //左递归
BTreePostOrder(root->_right); //右递归
printf("%d ", root->_data); //访问根
}
//层序遍历
void BTreeLevelOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
Queue q;
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
QDataType first = QueueFront(&q);
QueuePop(&q);
printf("%d ", first->_data);
if (first->_left)
{
QueuePush(&q, first->_left);
}
if (first->_right)
{
QueuePush(&q, first->_right);
}
}
}
//总节点数
//子问题:每棵树的节点数=该树的根节点(1)+左子树的节点数+右子树的节点数
size_t BTreeSize(BTNode* root)
{
if (root == NULL)
{
return 0;
}
return 1 + BTreeSize(root->_left) + BTreeSize(root->_right);
}
//叶子节点数
//子问题:每棵树的叶子节点数=左子树的叶子节点数+右子树的叶子节点数
size_t BTreeLeafSize(BTNode* root)
{
if (root == NULL)
{
return 0;
}
else if (root->_left == NULL&&root->_right == NULL)
{
return 1;
}
return BTreeLeafSize(root->_left) + BTreeLeafSize(root->_right);
}
//第K层节点数
//子问题:每棵树的第K层节点数=左子树的第k-1层节点数+右子树的第k-1层节点数
size_t BTreeKLevelSize(BTNode* root, size_t k)
{
if (root == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
return BTreeKLevelSize(root->_left, k - 1) + BTreeKLevelSize(root->_right, k - 1);
}
//深度
//子问题:每棵树的深度=左子树深度和右子树深度两者较大值+1
size_t BTreeDepth(BTNode* root)
{
if (root == NULL)
{
return 0;
}
size_t LeftDepth = BTreeDepth(root->_left);
size_t RightDepth = BTreeDepth(root->_right);
return LeftDepth > RightDepth ? (LeftDepth + 1) : (RightDepth + 1);
}
//查找
BTNode* BTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
{
return NULL;
}
if (root->_data == x)
{
return root;
}
BTNode* ret = BTreeFind(root->_left, x);
if (ret)
{
return ret;
}
return BTreeFind(root->_right, x);
}
//判断完全二叉树
int IsCompleteBTree(BTNode* root)
{
if (root == NULL)
{
return 1;
}
Queue q;
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q)) //找到队列里的第一个NULL
{
QDataType first = QueueFront(&q);
if (first == NULL)
{
break;
}
QueuePop(&q);
QueuePush(&q, first->_left);
QueuePush(&q, first->_right);
}
while (!QueueEmpty(&q)) //从第一个NULL后,判断是否有非NULL值出现
{
QDataType first = QueueFront(&q);
if (first) //若出现非NULL值,则为非完全二叉树
{
return 0;
}
QueuePop(&q);
}
return 1; //直到队列为空也没有出现非NULL值,则为完全二叉树
}
//判断完全二叉树,flag的方式判断
int IsCompleteBTree1(BTNode* root)
{
if (root == NULL)
{
return 1;
}
int flag = 0;
Queue q;
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
QDataType first = QueueFront(&q);
QueuePop(&q);
if (first->_left==NULL) //左子树
{
flag = 1;
}
else
{
if (flag == 1)
{
return 0;
}
QueuePush(&q, first->_left);
}
if (first->_right == NULL) //右子树
{
flag = 1;
}
else
{
if (flag == 1)
{
return 0;
}
QueuePush(&q, first->_right);
}
}
return 1;
}
//非递归先序遍历
void BTreePrevOrderNonR(BTNode* root)
{
Stack s;
StackInit(&s);
BTNode* cur = root;
while (cur || StackEmpty(&s) != 0)
//如果cur非NULL,则说明当前节点未遍历;如果栈s不为空,则说明右子树未遍历;只有当两个都为0时,才说明整个树遍历完
{
while (cur)
{
printf("%d ", cur->_data);
StackPush(&s, cur);
cur = cur->_left;
}
BTNode* top = StackTop(&s);
StackPop(&s);
cur = top->_right;
}
}
//非递归中序遍历
void BTreeInOrderNonR(BTNode* root)
{
Stack s;
StackInit(&s);
BTNode* cur = root;
while (cur || StackEmpty(&s) != 0)
{
while (cur)
{
StackPush(&s, cur);
cur = cur->_left;
}
BTNode* top = StackTop(&s);
printf("%d ", top->_data);
StackPop(&s);
cur = top->_right;
}
}
//非递归后序遍历
void BTreePostOrderNonR(BTNode* root)
{
Stack s;
StackInit(&s);
BTNode* cur = root;
BTNode* last = NULL; //last记录上一次访问节点,作为右子树访问标记
while (cur || StackEmpty(&s) != 0)
{
while (cur)
{
StackPush(&s, cur);
cur = cur->_left;
}
BTNode* top = StackTop(&s);
if (top->_right == last || top->_right == NULL) //如果top->_right == last,说明右子树上次已访问过
{
printf("%d ", top->_data);
last = top; //更新last
StackPop(&s);
}
else
{
cur = top->_right;
}
}
}
五、test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "BTree.h"
int main()
{
//int a[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6, '#', '#', '#' };
int a[] = { 1, 2, 3, '#', '#', '#', 5, 6, '#', '#', '#' };
size_t index = 0;
BTNode* tree = CreateBTree(a, &index, '#');
printf("先序遍历:");
BTreePrevOrder(tree);
printf("\n");
printf("非递归先序遍历:");
BTreePrevOrderNonR(tree);
printf("\n");
printf("中序遍历:");
BTreeInOrder(tree);
printf("\n");
printf("非递归中序遍历:");
BTreeInOrder(tree);
printf("\n");
printf("后序遍历:");
BTreePostOrder(tree);
printf("\n");
printf("非递归后序遍历:");
BTreePostOrder(tree);
printf("\n");
printf("层序遍历:");
BTreeLevelOrder(tree);
printf("\n");
printf("总节点数:%d\n", BTreeSize(tree));
printf("叶子节点数:%d\n", BTreeLeafSize(tree));
printf("第%d层节点数:%d\n", 2, BTreeKLevelSize(tree, 2));
printf("深度:%d\n", BTreeDepth(tree));
printf("是否为完全二叉树?%d\n", IsCompleteBTree(tree));
printf("是否为完全二叉树?%d\n", IsCompleteBTree1(tree));
if (BTreeFind(tree, 4))
{
printf("找到了\n");
}
else
{
printf("未找到\n");
}
system("pause");
return 0;
}
执行结果
(1)int a[] = { 1, 2, 3, ‘#’, ‘#’, 4, ‘#’, ‘#’, 5, 6, ‘#’, ‘#’, ‘#’ };
(2)int a[] = { 1, 2, 3, ‘#’, ‘#’, ‘#’, 5, 6, ‘#’, ‘#’, ‘#’ };