目录
一、为实现二叉树的层序遍历要借用队列的功能
1.Queue.c
#include "Queue.h"
//初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}
//入队---队尾入
void Queuepush(Queue* pq, DataTyPe x)
{
QNode* newnode = (QNode*)malloc(sizeof(QNode));
//判断内存申请是否成功
if (newnode == NULL)
{
perror("malloc");
return;
}
else
{
newnode->data = x;
newnode->next = NULL;
}
if (pq->tail == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
//出队--队头出
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->head);
//当只有一个数据时---这样做可以防止tail成为野指针
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
}
//计算队列数据个数
int QueueSize(Queue* pq)
{
assert(pq);
int size = 0;
QNode* cur = pq->head;
while (cur)
{
size++;
cur = cur->next;
}
return size;
}
//找到队头的数据
DataTyPe QueueFront(Queue* pq)
{
assert(pq);
assert(pq->head);
return pq->head->data;
}
//找到队尾的数据
DataTyPe QueueBack(Queue* pq)
{
assert(pq);
assert(pq->head);
return pq->tail->data;
}
//判空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}
//销毁
void QueueDestory(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
}
2.Queue.h
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct BinaryTreeNode* DataTyPe;
typedef struct QueueNode
{
struct QueueNode* next;
DataTyPe data;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
}Queue;
//初始化
void QueueInit(Queue* pq);
//入队---队尾入
void Queuepush(Queue* pq, DataTyPe x);
//出队--队头出
void QueuePop(Queue* pq);
//计算队列数据个数
int QueueSize(Queue* pq);
//找到队头的数据
DataTyPe QueueFront(Queue* pq);
//找到队尾的数据
DataTyPe QueueBack(Queue* pq);
//判空
bool QueueEmpty(Queue* pq);
//销毁
void QueueDestory(Queue* pq);
二、二叉树
1.BinaryTree.h
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int* pi);
// 二叉树销毁
void BinaryTreeDestory(BTNode* root);
// 二叉树节点个数
int BinaryTreeSize(BTNode* root);
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root);
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root);
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root);
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root);
// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root);
2.BinaryTree.c
#include "BinaryTree.h"
#include "Queue.h"
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{
assert(a);
if (a[*pi] == '#')
{
(*pi)++;
return NULL;
}
BTNode* root = (BTNode*)malloc(sizeof(BTNode));
root->data = a[*pi];
(*pi)++;
//返回时连接上
root->left = BinaryTreeCreate(a, pi);
root->right = BinaryTreeCreate(a, pi);
return root;
}
// 二叉树销毁
void BinaryTreeDestory(BTNode* root)
{
if (root == NULL)
return;
//后序销毁
BinaryTreeDestory(root->left);
BinaryTreeDestory(root->right);
free(root);
}
// 二叉树节点个数---左子树节点个数加右子树节点个数 + 1
int BinaryTreeSize(BTNode* root)
{
if (root == NULL)
return 0;
return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}
// 二叉树叶子节点个数---左子树叶子节点个数加右子树叶子节点个数 + 1
int BinaryTreeLeafSize(BTNode* root)
{
if (root == NULL)
return 0;
if (root->left == NULL && root->right == NULL)
return 1;
return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
if (root == NULL)
return 0;
//到达k层
if (k == 1)
return 1;
return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
return NULL;
if (root->data == x)
return root;
return BinaryTreeFind(root->left, x) ||
BinaryTreeFind(root->right, x);
}
// 二叉树前序遍历
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)
{
Queue q;
QueueInit(&q);
if (root != NULL)
{
Queuepush(&q, root);
}
while (!QueueEmpty(&q))
{
DataTyPe front = QueueFront(&q);
QueuePop(&q);
printf("%c ", front->data);
if(front->left)
Queuepush(&q, front->left);
if(front->right)
Queuepush(&q, front->right);
}
printf("\n");
QueueDestory(&q);
}
// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root)
{
Queuepush(&q, root);
}
while (!QueueEmpty(&q))
{
DataTyPe front = QueueFront(&q);
QueuePop(&q);
//遇到空退出
if (front == NULL)
break;
//空也入
Queuepush(&q, front->left);
Queuepush(&q, front->right);
}
//检查是否有非空,有这不是完全二叉树
while (!QueueEmpty(&q))
{
DataTyPe front = QueueFront(&q);
QueuePop(&q);
if (front != NULL)
{
QueueDestory(&q);
return false;
}
}
QueueDestory(&q);
return true;
}
3.Test.c
#include "BinaryTree.h"
void Test1()
{
char a[] = { "ABD##E#H##CF##G##" };
int i = 0;
BTNode* root = BinaryTreeCreate(a, &i);
BinaryTreePrevOrder(root);
printf("\n");
BinaryTreeInOrder(root);
printf("\n");
BinaryTreePostOrder(root);
printf("\n");
BinaryTreeDestory(root);
}
void Test2()
{
char str[] = { "ABD##E#H##CF##G##" };
int i = 0;
BTNode* root = BinaryTreeCreate(str, &i);
int a = BinaryTreeSize(root);
int b = BinaryTreeLeafSize(root);
int k = 3;
int c = BinaryTreeLevelKSize(root, k);
printf("二叉树节点个数:%d\n二叉树叶子节点个数:%d\n二叉树第%d层节点个数%d\n", a, b, k, c);
BinaryTreeDestory(root);
}
void Test3()
{
char str[] = { "ABD##E#H##CF##G##" };
int i = 0;
BTNode* root = BinaryTreeCreate(str, &i);
char x = 'A';
BTNode* findroot = BinaryTreeFind(root, x);
if (findroot == NULL)
{
printf("找不到%c\n", x);
return;
}
printf("找到%c\n", findroot->data);
BinaryTreeDestory(root);
}
//测试层序遍历
void Test4()
{
char str[] = { "ABD##E#H##CF##G##" };
int i = 0;
BTNode* root = BinaryTreeCreate(str, &i);
BinaryTreeLevelOrder(root);
BinaryTreeDestory(root);
}
//测试是否为完全二叉树
void Test5()
{
char str1[] = { "ABD##E##CF##G##" };
int i = 0;
BTNode* root1 = BinaryTreeCreate(str1, &i);
char str2[] = { "ABD##E#H##CF##G##" };
int j = 0;
BTNode* root2 = BinaryTreeCreate(str2, &j);
if (BinaryTreeComplete(root1))
printf("is full binary tree\n");
else
printf("no full binary tree\n");
if (BinaryTreeComplete(root2))
printf("is full binary tree\n");
else
printf("no full binary tree\n");
BinaryTreeDestory(root1);
BinaryTreeDestory(root2);
}
int main()
{
//Test1();
//Test2();
//Test3();
//Test4();
Test5();
return 0;
}