数据结构C语言 《四》二叉树链式的实现及操作《下》
Posted 程序猿是小贺
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构C语言 《四》二叉树链式的实现及操作《下》相关的知识,希望对你有一定的参考价值。
二叉树的链式结构的实现
二叉树链式结构的遍历
遍历指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。
二叉树链式结构的实现–核心模块
开辟空间
BTNode* BuyBinaryTreeNode(BTDataType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
if (NULL == node)
{
assert(0);
return NULL;
}
node->data = x;
node->left = node->right = NULL;
return node;
}
创建二叉树
// index按照值的方式传递的—在递归过程中对index修改之后,不会将修改之后的结果带到上一层中
// 所以这里要对index传址调用
BTNode* _BinaryTreeCreate(BTDataType a[], int n, int *index, BTDataType invalid)
{
BTNode *root = NULL;
if (*index < n && a[*index] != invalid)
{
//创建根节点
root = BuyBinaryTreeNode(a[*index]);
//创建左子树
(*index)++;
root->left = _BinaryTreeCreate(a, n, index, invalid);
//创建右子树
(*index)++;
root->right = _BinaryTreeCreate(a, n, index, invalid);
}
return root;
}
BTNode* BinaryTreeCreate(BTDataType a[], int n, BTDataType invalid)
{
int index = 0;
return _BinaryTreeCreate(a, n, &index,invalid);
}
二叉树销毁
void BinaryTreeDestory(BTNode** root)
{
assert(root);
if (NULL == *root)
{
return;
}
//按照后序遍历进行销毁
BinaryTreeDestory(&(*root)->left);
BinaryTreeDestory(&(*root)->right);
free(*root);
*root = NULL;
}
二叉树节点个数
int BinaryTreeSize(BTNode* root)
{
if (root == NULL)
return 0;
return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}
二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{
//判断该节点是否为空,返回值为0
if (root == NULL)
return 0;
//判断其左右子树是否为空,都为空则返回1
if (root->left == NULL && root->right == NULL)
return 1;
//递归
return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}
二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
//判断是否为空树或者k的值是否小于等于0
if (root == NULL || k <= 0)
return 0;
//树不空并且k = 1
if (k == 1)
return 1;
//k > 1
return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}
求树的高度
int BinTreeHeight(BTNode *root)
{
if (root == NULL)
{
return 0;
}
//左右子树高度加1 即为树的高度
int leftHeight = BinTreeHeight(root->left);
int rightHeight = BinTreeHeight(root->right);
return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}
二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
BTNode *ret = NULL;
if (NULL == root)
return NULL;
if (x == root->data)
return root;
if (ret == BinaryTreeFind(root->left, x))
return ret;
return BinaryTreeFind(root->right, x);
}
二叉树前序遍历(递归)
void BinaryTreePrevOrder(BTNode* root)
{
if (root)
{
printf("%c ", root->data);
BinaryTreePrevOrder(root->left);
BinaryTreePrevOrder(root->right);
}
}
二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
if (root)
{
BinaryTreeInOrder(root->left);
printf("%c ", root->data);
BinaryTreeInOrder(root->right);
}
}
二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
if (root)
{
BinaryTreePostOrder(root->left);
BinaryTreePostOrder(root->right);
printf("%c ", root->data);
}
}
层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{
Queue q;
if (root == NULL)
{
assert(0);
return;
}
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* cur = QueueFront(&q);
printf("%c ", cur->data);
if (cur->left)
{
QueuePush(&q, cur->left);
}
if (cur->right)
{
QueuePush(&q, cur->right);
}
QueuePop(&q);
}
QueueDestroy(&q);
}
判断是否是完全二叉树
int BinaryTreeComplete(BTNode* root)
{
Queue q;
int flag = 0;
//空树
if (root == NULL)
return 1;
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* cur = QueueFront(&q);
if (flag)
{
//从第一个不饱和的节点后,所有结点都不能有孩子
if (cur->left || cur->right)
{
QueueDestroy(&q);
return 0;
}
}
//找树中第一个不饱和的结点
else
{
if (cur->left && cur->right)
{
QueuePush(&q, cur->left);
QueuePush(&q, cur->right);
flag = 1;
}
else if (cur->left)
{
QueuePush(&q, cur->left);
flag = 1;
}
else if (cur->right)
{
QueueDestroy(&q);
return 0;
}
else
{
flag = 1;
}
}
QueuePop(&q);
}
QueueDestroy(&q);
return 1;
}
二叉树链式结构的实现–全代码
Queue.h
#pragma once
struct BTNode;//前置声明
typedef struct BinaryTreeNode* QDataType;
typedef struct QListNode
{
struct QListNode* next;
QDataType data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* front;
QNode* rear;
}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"
#include<assert.h>
#include<stdio.h>
#include<malloc.h>
QNode* BuyQueueNode(QDataType data)
{
QNode* node = (QNode *)malloc(sizeof(QNode));
if (NULL == node)
{
assert(0);
return NULL;
}
node->data = data;
node->next = NULL;
return node;
}
// 初始化队列
void QueueInit(Queue* q)
{
assert(q);
q->front = q->rear = BuyQueueNode(0);
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data)
{
assert(q);
q->rear->next = BuyQueueNode(data);
q->rear = q->rear->next;
}
// 队头出队列
void QueuePop(Queue* q)
{
QNode *delNode = NULL;
if (QueueEmpty(q))
return;
delNode = q->front->next;
q->front->next = delNode->next;
//如果队列中此时只有一个元素,将该元素删除后还需将rear放在front的位置
if (delNode->next == NULL)
q->rear = q->front;
free(delNode);
}
// 获取队列头部元素
QDataType QueueFront(Queue* q)
{
assert(!QueueEmpty(q));
return q->front->next->data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q)
{
assert(!QueueEmpty(q));
return q->rear->data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q)
{
assert(q);
int count = 0;
QNode* cur = q->front->next;
while (cur)
{
cur = cur->next;
count++;
}
return count;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q)
{
assert(q);
return q->front->next == NULL;
}
// 销毁队列
void QueueDestroy(Queue* q)
{
assert(q);
QNode* cur = q->front;
while (cur)
{
q->front = cur->next;
free(cur);
cur = q->front;
}
q->front = q->rear = NULL;
}
BinTree.h
#pragma once
typedef char BTDataType;
//孩子表示法
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
// 构建二叉树
BTNode* BinaryTreeCreate(BTDataType a[], int n,BTDataType invalid);
// 二叉树销毁
void BinaryTreeDestory(BTNode** root);
// 二叉树节点个数
int BinaryTreeSize(BTNode* root);
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
//求树的高度
int BinTreeHeight(BTNode *root);
// 二叉树查找值为x的节点
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 TestBinTree();
BinTree.c
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include "BinaryTree.h"
#include "Queue.h"
//开辟空间
BTNode* BuyBinaryTreeNode(BTDataType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
if (NULL == node)
{
assert(0);
return NULL;
}
node->data = x;
node->left = node->right = NULL;
return node;
}
//创建二叉树
// index按照值的方式传递的---在递归过程中对index修改之后,不会将修改之后的结果带到上一层中
// 所以这里要对index传址调用
BTNode* _BinaryTreeCreate(BTDataType a[], int n, int *index, BTDataType invalid)
{
BTNode *root = NULL;
if (*index < n && a[*index] != invalid)
{
//创建根节点
root = BuyBinaryTreeNode(a[*index]);
//创建左子树
(*index)++;
root->left = _BinaryTreeCreate(a, n, index, invalid);
//创建右子树
(*index)++;
root->right = _BinaryTreeCreate(a, n, index, invalid);
}
return root;
}
BTNode* BinaryTreeCreate(BTDataType a[], int n, BTDataType invalid)
{
int index = 0;
return _BinaryTreeCreate(a, n, &index,invalid);
}
// 二叉树销毁
void BinaryTreeDestory(BTNode** root以上是关于数据结构C语言 《四》二叉树链式的实现及操作《下》的主要内容,如果未能解决你的问题,请参考以下文章
两万字硬核解析树与二叉树所有基本操作(包含堆,链式二叉树基本操作及测试代码,和递归函数的书写方法)