二叉树的实现(包括层序遍历)
queue.h文件
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
typedef struct BinaryTreeNode* QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType x;
}QNode;
typedef struct Queue
{
QNode* head;//头指针
QNode* tail;//尾指针
int size;//队列长度
}Queue;
// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列队尾元素
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);
queue.c文件
#include"queue.h" // 引入头文件"queue.h"
// 队列初始化
void QueueInit(Queue* q) // 参数为队列指针
{
assert(q); // 断言队列指针不为空
q->head = q->tail = NULL; // 首尾全部指向NULL,即队列为空
q->size = 0; // 元素个数为0
}
QNode* Buy_Node(QDataType x) // 定义一个函数,用来创建一个新节点
{
QNode* newnode = (QNode*)malloc(sizeof(QNode)); // 申请一个新节点
if (newnode == NULL) // 如果申请失败
{
perror("malloc fail:"); // 输出错误信息
return 0; // 返回0
}
newnode->x = x; // 新节点的数据为x
newnode->next = NULL; // 新节点的next指针指向NULL,即没有下一个节点
return newnode; // 返回新节点
}
// 队头入队列
void QueuePush(Queue* q, QDataType data) // 参数为队列指针和要插入的数据
{
assert(q); // 断言队列指针不为空
QNode* newnode = Buy_Node(data); // 创建一个新节点
if (q->head == NULL) // 如果队列为空
{
assert(q->tail == NULL); // 断言队列尾指针也为空
q->head = q->tail = newnode; // 头指针和尾指针都指向新节点
}
else // 如果队列不为空
{
q->tail->next = newnode; // 队列尾部的next指针指向新节点
q->tail = newnode; // 队列尾指针指向新节点
}
q->size++; // 元素个数加1
}
// 队头出队列
void QueuePop(Queue* q) // 参数为队列指针
{
assert(q); // 断言队列指针不为空
assert(q->head != NULL); // 断言队列头指针不为空
if (q->head->next == NULL) // 如果队列只有一个元素
{
free(q->head); // 释放头节点的内存
q->head = q->tail = NULL; // 头指针和尾指针都指向NULL,即队列为空
}
else // 如果队列不止一个元素
{
QNode* second = q->head->next; // 保存第二个节点的指针
free(q->head); // 释放头节点的内存
q->head = second; // 将原来的第二个节点设置为头节点
}
q->size--; // 元素个数减1
}
// 获取队列头部元素
QDataType QueueFront(Queue* q) // 参数为队列指针
{
return q->head->x; // 返回头节点的数据
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q) // 参数为队列指针
{
return q->tail->x; // 返回尾节点的数据
}
// 获取队列中有效元素个数
int QueueSize(Queue* q) // 参数为队列指针
{
return q->size; // 返回元素个数
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q) // 参数为队列指针
{
return q->size == 0; // 如果元素个数为0,返回1,否则返回0
}
// 销毁队列
void QueueDestroy(Queue* q) // 参数为队列指针
{
assert(q); // 断言队列指针不为空
QNode* cur = q->head; // 定义一个指针cur指向队列头节点
while (cur) // 循环直到cur为NULL
{
QNode* second = cur->next; // 保存下一个节点的指针
free(cur); // 释放当前节点的内存
cur = second; // 将cur指向下一个节点
}
q->head = q->tail = NULL; // 头指针和尾指针都指向NULL,即队列为空
q->size = 0; // 元素个数为0
}
test.c文件
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"queue.h"
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
BTNode* BuyNode(BTDataType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
if (node == NULL)
{
perror("malloc fail");
exit(-1);
}
node->data = x;
node->left = NULL;
node->right = NULL;
return node;
}
BTNode* CreatTree()
{
//创建节点
BTNode* node1 = BuyNode(1);
BTNode* node2 = BuyNode(2);
BTNode* node3 = BuyNode(3);
BTNode* node4 = BuyNode(4);
BTNode* node5 = BuyNode(5);
BTNode* node6 = BuyNode(6);
BTNode* node7 = BuyNode(7);
BTNode* node8 = BuyNode(8);
BTNode* node9 = BuyNode(9);
BTNode* node10 = BuyNode(10);
//建树
node1->left = node2;
node1->right = node4;
node2->left = node3;
node4->left = node5;
node4->right = node6;
node3->right = node7;
node7->left = node8;
node5->right = node9;
node9->left = node10;
return node1;
}
// 二叉树前序遍历
//前序遍历为 中->左->右
void PreOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL->");
return;
}
printf("%d->", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
// 二叉树中序遍历
//中序遍历为 左->中->右
void InOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL->");
return;
}
InOrder(root->left);
printf("%d->", root->data);
InOrder(root->right);
}
// 二叉树后序遍历
//后序遍历为 左->右->中
void PostOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL->");
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%d->", root->data);
}
//求节点的个数
int TreeSize(BTNode* root)
{
if (root == NULL)
{
return 0;
}
return TreeSize(root->left)+ TreeSize(root->right) + 1;//递归了左子树,然后递归右子树,再加上自身的节点数(1)
}
//求高度
int TreeHeight(BTNode* root)
{
if (root == NULL)
{
return 0;
}
int LeftHight = TreeHeight(root->left);
int RightHight = TreeHeight(root->right);
return LeftHight > RightHight ? LeftHight + 1 : RightHight + 1;
}
//得到第k层有多少个节点
int TreeKLevel(BTNode* root, int k)
{
assert(k > 0);
if (root == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
int left = TreeKLevel(root->left, k - 1);
int right = TreeKLevel(root->right, k - 1);
return left + right;
//return TreeKLevel(root->left, k - 1) + TreeKLevel(root->right, k - 1);
}
BTNode* TreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
{
return NULL;
}
if (root->data == x)
{
return root;
}
BTNode* left = TreeFind(root->left,x);
if (left != NULL)
{
return left;
}
BTNode* right = TreeFind(root->right,x);
if (right != NULL)
{
return right;
}
return NULL;
}
//层序遍历->宽度优先搜索
void BFS(BTNode* root)
{
Queue q;//建立队列
QueueInit(&q);//初始化队列
if (root)
{
QueuePush(&q, root);//先将第一个节点入队列
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);//出队
printf("%d->", front->data);
if (front->left)
{
QueuePush(&q, front->left);
}
if (front->right)
{
QueuePush(&q, front->right);
}
}
//销毁队列
QueueDestroy(&q);
}
int main(void)
{
BTNode* root=CreatTree();
printf("前序遍历: ");
PreOrder(root);
puts("");
printf("中序遍历: ");
InOrder(root);
puts("");
printf("后序遍历: ");
PostOrder(root);
puts("");
printf("节点个数为:%d", TreeSize(root));
puts("");
printf("树的高度为: %d", TreeHeight(root));
puts("");
printf("第3层有%d个节点", TreeKLevel(root, 3));
puts("");
BTNode* find = TreeFind(root, 5);
PreOrder(find);
puts("");
BFS(root);
return 0;
}
