数据结构
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType _data;
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
}BTNode;
声明的函数
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);
创建二叉树
BTNode* BinaryTreeCreate(BTDataType* pi, int* u)
{
if (pi[*u] == '#')
{
(*u)++;
return NULL;
}
BTNode* a = malloc(sizeof(BTNode));
a->_data = pi[(*u)++];
a->_left = BinaryTreeCreate(pi, u);
a->_right = BinaryTreeCreate(pi, u);
return a;
}
这里采用的是前序遍历,节点为空‘#’代替,字符串生成二叉树
检查二叉树节点个数
int BinaryTreeSize(BTNode* root)
{
if (root == NULL)
return 0;
return BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 1;
}
如果节点为空,就返回空,不是空就加1再向下去递归
判断有几个叶节点
int BinaryTreeLeafSize(BTNode* root)
{
if ((root->_left&&root->_right) == NULL)
return 1;
return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}
第k层有几个节点
int BinaryTreeLevelKSize(BTNode* root, int k)
{
if (root == NULL)
return 0;
if (k == 1)
return 1;
return BinaryTreeLevelKSize(root->_left, k - 1) + BinaryTreeLevelKSize(root->_right, k - 1);
}
check值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
return NULL;
if (root->_data == x)
return root;
BTNode* r = BinaryTreeFind(root->_left, x);
if (r)
return r;
return BinaryTreeFind(root->_right, x);
}
二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root)
{
if (root==NULL)
return;
printf("%d", root->_data);
BinaryTreePrevOrder(root->_left);
BinaryTreePrevOrder(root->_right);
}
二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
if (root == NULL)
return;
BinaryTreeInOrder(root->_left);
printf("%d", root->_data);
BinaryTreeInOrder(root->_right);
}
输出后序遍历
void BinaryTreePostOrder(BTNode* root)
{
if (root == NULL)
return;
BinaryTreePostOrder(root->_left);
BinaryTreePostOrder(root->_right);
printf("%d", root->_data);
}
二叉树层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{
q* d = malloc(sizeof(q));
linit(d);
if (root)
push(d, root);
while (empty(d))
{
root = d->head->o;
printf("%c ", d->head->o->_data);
pop(d);
if (root->_left)
push(d,root->_left);
if (root->_right)
push(d, root->_right);
}
}
因为二叉树层序遍历是逐层递进,队列更符合数据储存的方式,把第一个队列第一个节点出队列,就把相应的子节点入队列,队列没有数据遍历完
队列的代码
game.c
#pragma once
#include"game.h"
#define LtData BTNode *
#include<stdbool.h>
typedef struct list
{
LtData o;
struct list* nod;
}node;
typedef struct queue
{
node* head;
node* list;
int size;
}q;
void* linit(q* e);
void push(q* list, LtData x);
void pop(q* list);
bool empty(q* list);
void destroy(q* list);
LtData backnum(q* q);
int queuesize(q* q);
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"dl.h"
#include<assert.h>
#include<stdio.h>
#include<stdbool.h>
#include<ctype.h>
void* linit(q* e)
{
e->head = e->list = NULL;
e->size = 0;
}
void push(q* q, LtData x)
{
node* tail = malloc(sizeof(node));
tail->o = x;
tail->nod = NULL;
assert(q);
if (q->head == NULL)
{
q->head = tail;
q->list = tail;
}
else
{
q->list->nod = tail;
q->list = q->list->nod;
}
q->size++;
}
void pop(q* q)
{
assert(q);
assert(empty(q));
if (q->head == q->list)
{
free(q->head);
q->head = q->list = NULL;
}
else
{
node* p = q->head;
q->head = q->head->nod;
free(p);
}
q->size--;
}
bool empty(q* q)
{
if (q->size == 0)
return false;
return true;
}
void destroy(q* q)
{
assert(q);
assert(q->head);
while (q->head)
{
node* e = q->head;
q->head = q->head->nod;
free(e);
}
q->list = 0;
q->size = 0;
}
int queuesize(q* q)
{
return q->size;
}
LtData backnum(q* q)
{
return q->list->o;
}
判断是不是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
q* d = malloc(sizeof(q));
linit(d);
if (root)
push(d, root);
while (empty(d))
{
root = d->head->o;
pop(d);
if (root == NULL)
break;
push(d, root->_left);
push(d, root->_right);
}
while (empty(d))
{
root = d->head->o;
if (root != NULL)
return false;
pop(d);
}
return true;
}
通过层序遍历,但是把null也入队列,如果出栈的那个元素是null,那就进入下一个循环,如果出栈遇到不是null的元素,那就不是完全二叉树
销毁二叉树
后序遍历销毁节点,这种遍历会从叶节点一直返回溯到第一个根节点
void BinaryTreeDestory(BTNode** root)
{
BTNode* r = *root;
if (r == NULL)
return;
BinaryTreeDestory(&r->_left);
free(r->_left);
BinaryTreeDestory(&r->_right);
free(r->_right);
free(r);
*root = NULL;
}