前言
本文总结学习普通二叉树(链式结构)接口实现-C语言。
一、普通二叉树(链式结构)基本结构构建
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "Queue.h"
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
BTNode* BuyBTNode(BTDataType x)
{
BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
assert(newnode);
newnode->data = x;
newnode->left = NULL;
newnode->right = NULL;
return newnode;
}
BTNode* CreatBinaryTree()
{
BTNode* node1 = BuyBTNode(1);
BTNode* node2 = BuyBTNode(2);
BTNode* node3 = BuyBTNode(3);
BTNode* node4 = BuyBTNode(4);
BTNode* node5 = BuyBTNode(5);
BTNode* node6 = BuyBTNode(6);
BTNode* test = BuyBTNode(99);
node1->left = node2;
node2->left = node3;
node1->right = node4;
node2->right = test;
node4->left = node5;
node4->right = node6;
return node1;
}
二、前序遍历(先根遍历)
void PreOrder(BTNode* root)
{
if (NULL == root)
{
printf("NULL ");
return;
}
printf("%d ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
三、中序遍历
void InOrder(BTNode* root)
{
if (NULL == root)
{
printf("NULL ");
return;
}
InOrder(root->left);
printf("%d ", root->data);
InOrder(root->right);
}
四、后序遍历
void PostOrder(BTNode* root)
{
if (NULL == root)
{
printf("NULL ");
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%d ", root->data);
}
五、二叉树结点个数
int BTreeSize(BTNode* root)
{
return (NULL == root) ? 0 : \
1 + BTreeSize(root->left) + \
BTreeSize(root->right);
}
六、二叉树叶子结点个数
int BTreeLeafSize(BTNode* root)
{
if (NULL == root)
{
return 0;
}
return (NULL == root->left && NULL == root->right) ? 1 : \
BTreeLeafSize(root->left) + BTreeLeafSize(root->right);
}
七、二叉树第k层结点个数(k >= 1)
int BTreeLevelSize(BTNode* root, int k)
{
assert(k >= 1);
if (NULL == root)
{
return 0;
}
return (1 == k) ? 1 : \
BTreeLevelSize(root->left, k - 1) + \
BTreeLevelSize(root->right, k - 1);
}
八、求二叉树高度
int BTreeDepth(BTNode* root)
{
if (NULL == root)
{
return 0;
}
else
{
int leftDepth = BTreeDepth(root->left);
int rightDepth = BTreeDepth(root->right);
return (leftDepth > rightDepth) ? \
1 + leftDepth : 1 + rightDepth;
}
}
九、二叉树查找值为x的结点
BTNode* BTreeFind(BTNode* root, BTDataType x)
{
if (NULL == root)
{
return NULL;
}
if (x == root->data)
{
return root;
}
BTNode* ret1 = BTreeFind(root->left, x);
if (NULL != ret1)
{
return ret1;
}
BTNode* ret2 = BTreeFind(root->right, x);
if (NULL != ret2)
{
return ret2;
}
return NULL;
}
十、二叉树销毁
void BTreeDestory(BTNode** proot)
{
if (NULL == *proot)
{
return;
}
BTreeDestory(&((*proot)->left));
BTreeDestory(&((*proot)->right));
free(*proot);
*proot = NULL;
}
十一、二叉树层序遍历(需要借助队列)
借助的队列代码_Queue.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (NULL != cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = NULL;
pq->tail = NULL;
}
void QueuePush(Queue* pq, QDataType val)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (NULL == newnode)
{
printf("malloc fail\n");
exit(-1);
}
else
{
newnode->next = NULL;
newnode->val = val;
if (NULL == pq->tail)
{
pq->head = newnode;
pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
}
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->head && pq->tail);
if (NULL == pq->head->next)
{
free(pq->head);
pq->head = NULL;
pq->tail = NULL;
}
else
{
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return NULL == pq->tail;
}
size_t QueueSize(Queue* pq)
{
assert(pq);
size_t num = 0;
QNode* cur = pq->head;
while (NULL != cur)
{
num++;
cur = cur->next;
}
return num;
}
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(pq->head);
return pq->head->val;
}
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(pq->tail);
return pq->tail->val;
}
借助的队列代码_Queue.h:
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
struct BinaryTreeNode;
typedef struct BinaryTreeNode* QDataType;
typedef struct QListNode
{
struct QListNode* next;
QDataType val;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
}Queue;
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType val);
void QueuePop(Queue* pq);
bool QueueEmpty(Queue* pq);
size_t QueueSize(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
层序遍历代码:
void LevelOrder(BTNode* root)
{
if (NULL == root)
{
printf("root NULL\n");
return;
}
Queue q = { 0 };
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
printf("%d ", front->data);
QueuePop(&q);
if (front->left)
{
QueuePush(&q, front->left);
}
if (front->right)
{
QueuePush(&q, front->right);
}
}
QueueDestroy(&q);
}
十二、判断二叉树是否为完全二叉树(需要借助队列)
借助队列同十一章节队列
bool BTreeComplete(BTNode* root)
{
Queue q = { 0 };
QueueInit(&q);
if (NULL == root)
{
QueuePush(&q, root);
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (NULL == front)
{
break;
}
else
{
QueuePush(&q, front->left);
QueuePush(&q, front->right);
}
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front)
{
QueueDestroy(&q);
return false;
}
}
QueueDestroy(&q);
return true;
}
十三、测试代码:
int main()
{
BTNode* tree = CreatBinaryTree();
PreOrder(tree);
printf("\n");
InOrder(tree);
printf("\n");
PostOrder(tree);
printf("\n");
printf("Size:%d\n", BTreeSize(tree));
printf("LeafSize:%d\n", BTreeLeafSize(tree));
printf("LevelSize:%d\n", BTreeLevelSize(tree, 3));
printf("Depth:%d\n", BTreeDepth(tree));
for (int i = 1; i <= 7; i++)
{
BTNode* ret = BTreeFind(tree, i);
printf("BTreeFind:%d %p\n", i, ret);
}
LevelOrder(tree);
printf("\n");
if (BTreeComplete(tree))
{
printf("该树是完全二叉树\n");
}
else
{
printf("该树不是完全二叉树\n");
}
BTreeDestory(&tree);
return 0;
}
总结
这里对文章进行总结: 以上就是今天总结的内容,本文包括了C语言实现普通二叉树(链式结构)各个接口,分享给大家。 真💙欢迎各位给予我更好的建议,欢迎访问!!!小编创作不易,觉得有用可以一键三连哦,感谢大家。peace 希望大家一起坚持学习,共同进步。梦想一旦被付诸行动,就会变得神圣。
欢迎各位大佬批评建议,分享更好的方法!!!🙊🙊🙊
|