目录
一、基本概念
- 节点的度:一个节点含有的子树的个数称为该节点的度
- 叶节点或终端节点:度为0的节点称为叶节点
- 非终端节点或分支节点:度不为0的节点
- 双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点
- 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点
- 兄弟节点:具有相同父节点的节点互称为兄弟节点
- 树的度:一棵树中,最大的节点的度称为树的度
- 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推
- 树的高度或深度:树中节点的最大层次
- 堂兄弟节点:双亲在同一层的节点互为堂兄弟
- 节点的祖先:从根到该节点所经分支上的所有节点
- 子孙:以某节点为根的子树中任一节点都称为该节点的子孙
- 森林:由m(m>0)棵互不相交的树的集合称为森林
二、基本操作
(一)先序遍历
1.图解
2.代码
void PreOrder(BTNode* root)//先序遍历
{
if (root == NULL)
{
printf("NULL ");
return;
}
printf("%d ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
(二)中序遍历
1.图解
2.代码
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);
}
(四)求结点个数
1.图解
2.代码
int BTreeSize(BTNode* root)//求结点个数
{
if (root == NULL)
return 0;
return BTreeSize(root->left)
+ BTreeSize(root->right) + 1;//左子树的结点+右子树结点+再加其本身一个
}
(五)叶子结点个数
1.图解
2.代码
int BTreeLeafSize(BTNode* root)//叶子结点个数
{
if (root == NULL)
return 0;
if (root->left == NULL && root->right == NULL)
return 1;
return BTreeLeafSize(root->left) + BTreeLeafSize(root->right);
}
(六)树的高度
1.图解
2.代码
int BTreeHeight(BTNode* root)//树的高度
{
if (root == NULL)
return 0;
int leftH = BTreeHeight(root->left);
int rightH = BTreeHeight(root->right);
return leftH > rightH ? leftH + 1 : rightH + 1;
}
(七)求树第k层的结点数量
1.图解
2.代码
int BTreeLevelK(BTNode* root, int k)//第k层结点个数
{
if (root == NULL)
return 0;
//后面意味着root都不为空
if (k == 1)
return 1;
k = k - 1;
return BTreeLevelK(root->left, k)
+ BTreeLevelK(root->right, k);
}
(八)查找数据是x的结点
BTNode* BTreeFind(BTNode* root, BTDataType x)//查找数据是x的结点
{
if (root == NULL)
return NULL;
if (root->data == x)
return root;
int ret1 = BTreeFind(root->left, x);//记录左树查找的结果
int ret2 = BTreeFind(root->right, x);//记录右树查找的结果
if (ret1 != NULL)
return ret1;
if (ret2 != NULL)
return ret2;
return NULL;
}
(九)销毁
void BTreeDestroy(BTNode* root)
{
if (root == NULL)
return true;
BTreeDestroy(root->left);
BTreeDestroy(root->right);
free(root);
}
(十)层序遍历
void LevelOrder(BTNode* root)//层序遍历
{
Queue q;
QInit(&q);
if (root)//根结点先入队
{
QPush(&q, root);
}
while (!ISEmpty(&q))//循环进队
{
BTNode* front = QFront(&q);//先保存对头结点
QPop(&q);
if (front != NULL)
{
printf("%d ", front->data);
if (front->left)
QPush(&q, front->left);
if (front->right)
QPush(&q, front->right);
}
}
}
(十一)判断是不是完全二叉树
bool BTreeComplete(BTNode* root)//判断完全二叉树
{
Queue q;
QInit(&q);
if (root)
QPush(&q,root);
while (!ISEmpty(&q))
{
BTNode* front = QFront(&q);
QPop(&q);
if (front!=NULL)
{
QPush(&q,front->left);
QPush(&q,front->right);
}
if (front == NULL)
break;
}
while (!ISEmpty(&q))
{
if(QFront(&q)== NULL)
QPop(&q);
else
{
QDestroy(&q);
return false;
}
}
QDestroy(&q);
return true;
}
三、完整代码
//BinaryTree.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
typedef int BTDataType;
typedef struct BinaryTree
{
BTDataType data;
struct BinaryTree* left;
struct BinaryTree* right;
}BTNode;
BTNode* NewNode(BTDataType x);//建立结点
BTNode* CreateTree();//创建一棵树
void PreOrder(BTNode* root);//先序遍历
void InOrder(BTNode* root);//中序遍历
void PostOrder(BTNode* root);//后序遍历
int BTreeSize(BTNode* root);//求结点个数
int BTreeLeafSize(BTNode* root);//叶子结点个数
int BTreeHeight(BTNode* root);//树的高度(左子树的高度+1/右子树的高度+1)
int BTreeLevelK(BTNode* root, int k);//第k层结点个数
BTNode* BTreeFind(BTNode* root, BTDataType x);//查找数据是x的结点
//BinaryTree.c
#include"BinaryTree.h"
BTNode* NewNode(BTDataType x)//建立结点
{
BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
if (newnode == NULL)
{
perror("malloc fail!");
return;
}
newnode->data = x;
newnode->left = NULL;
newnode->right = NULL;
return newnode;
}
BTNode* CreateTree()//创建一棵树
{
BTNode* node1=NewNode(12);
BTNode* node2 = NewNode(39);
BTNode* node3 = NewNode(46);
BTNode* node4 = NewNode(87);
BTNode* node5 = NewNode(66);
BTNode* node6 = NewNode(53);
//将结点连接起来
node1->left = node2;
node1->right = node3;
node2->left = node4;
node2->right = node5;
node3->left = node6;
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 BTreeSize(BTNode* root)//求结点个数
{
if (root == NULL)
return 0;
return BTreeSize(root->left) + BTreeSize(root->right) + 1;//左子树的结点+右子树结点+再加其本身一个
}
int BTreeLeafSize(BTNode* root)//叶子结点个数
{
if (root == NULL)
return 0;
if (root->left == NULL && root->right == NULL)
return 1;
return BTreeLeafSize(root->left) + BTreeLeafSize(root->right);
}
int BTreeHeight(BTNode* root)//树的高度
{
if (root == NULL)
return 0;
int leftH = BTreeHeight(root->left);
int rightH = BTreeHeight(root->right);
return leftH > rightH ? leftH + 1 : rightH + 1;
}
int BTreeLevelK(BTNode* root, int k)//第k层结点个数
{
if (root == NULL)
return 0;
//后面意味着root都不为空
if (k == 1)
return 1;
k = k - 1;
return BTreeLevelK(root->left, k)
+ BTreeLevelK(root->right, k);
}
BTNode* BTreeFind(BTNode* root, BTDataType x)//查找数据是x的结点
{
if (root == NULL)
return NULL;
if (root->data == x)
return root;
int ret1 = BTreeFind(root->left, x);//记录左树查找的结果
int ret2 = BTreeFind(root->right, x);//记录右树查找的结果
if (ret1 != NULL)
return ret1;
if (ret2 != NULL)
return ret2;
return NULL;
}
//Test.c
#include"BinaryTree.h"
int main()
{
BTNode* root = CreateTree();
// 12
// / \
// 39 46
// / \ /
// 87 66 53
//
//
printf("先序遍历:");
PreOrder(root);//先序遍历
printf("\n");
printf("中序遍历:");
InOrder(root);
printf("\n");
printf("后序遍历:");
PostOrder(root);
printf("\n");
//结点个数
printf("结点个数:");
printf("%d\n", BTreeSize(root));
//叶子结点个数
printf("叶子结点个数:");
printf("%d\n", BTreeLeafSize(root));
//树的高度
printf("树的高度:");
printf("%d\n", BTreeHeight(root));
BTNode* r = BTreeFind(root, 109);
if (r == NULL)
{
printf("未找到!\n");
}
else
{
printf("%d\n", r->data);
}
//求第k层的结点个数
int k = 3;
printf("第%d层结点数量:%d\n", k,BTreeLevelK(root,k));
return 0;
}
四、层序遍历+判断完全二叉树
//BinaryTree.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int BTDataType;
typedef struct BinaryTree
{
BTDataType data;
struct BinaryTree* left;
struct BinaryTree* right;
}BTNode;
BTNode* NewNode(BTDataType x);//建立结点
BTNode* CreateTree();//创建一棵树
void LevelOrder(BTNode* root);//层序遍历
bool BTreeComplete(BTNode* root);//判断完全二叉树
//队列的定义
typedef struct BinaryTree* ElemType;
typedef struct QueueNode
{
struct QueueNode* next;
ElemType data;
}QNode;
typedef struct Queue
{
QNode* phead;
QNode* tail;
int size;
}Queue;
void QInit(Queue* p);//初始化
void QDestroy(Queue* p);//销毁
bool ISEmpty(Queue* p);//判空
void QPush(Queue* p, ElemType x);//进队
void QPop(Queue* p);//出队
ElemType QFront(Queue* p);//获取队头元素
ElemType QBack(Queue* p);//获取队尾元素
//BinaryTree.c
#include"BinaryTree.h"
BTNode* NewNode(BTDataType x)//建立结点
{
BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
if (newnode == NULL)
{
perror("malloc fail!");
return;
}
newnode->data = x;
newnode->left = NULL;
newnode->right = NULL;
return newnode;
}
BTNode* CreateTree()//创建一棵树
{
BTNode* node1 = NewNode(12);
BTNode* node2 = NewNode(39);
BTNode* node3 = NewNode(46);
BTNode* node4 = NewNode(87);
BTNode* node5 = NewNode(66);
BTNode* node6 = NewNode(53);
//将结点连接起来
node1->left = node2;
node1->right = node3;
node2->left = node4;
node2->right = node5;
node3->right = node6;
return node1;
}
void LevelOrder(BTNode* root)//层序遍历
{
Queue q;
QInit(&q);
if (root)//根结点先入队
{
QPush(&q, root);
}
while (!ISEmpty(&q))//循环进队
{
BTNode* front = QFront(&q);//先保存对头结点
QPop(&q);
if (front != NULL)
{
printf("%d ", front->data);
if (front->left)
QPush(&q, front->left);
if (front->right)
QPush(&q, front->right);
}
}
}
bool BTreeComplete(BTNode* root)//判断完全二叉树
{
Queue q;
QInit(&q);
if (root)
QPush(&q,root);
while (!ISEmpty(&q))
{
BTNode* front = QFront(&q);
QPop(&q);
if (front!=NULL)
{
QPush(&q,front->left);
QPush(&q,front->right);
}
if (front == NULL)
break;
}
while (!ISEmpty(&q))
{
if(QFront(&q)== NULL)
QPop(&q);
else
{
QDestroy(&q);
return false;
}
}
QDestroy(&q);
return true;
}
//队列
void QInit(Queue* p)//初始化
{
assert(p);
p->phead = p->tail = NULL;
p->size = 0;
}
void QDestroy(Queue* p)//销毁
{
assert(p);
QNode* cur = p->phead;
while (cur != NULL)
{
QNode* next = cur->next;//先保存cur的下一个结点
free(cur);
cur = next;
}
p->phead = p->tail = NULL;
p->size = 0;
}
bool ISEmpty(Queue* p)//判空
{
assert(p);
return p->size == 0;
}
void QPush(Queue* p, ElemType x)//进队
{
assert(p);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail\n");
return;
}
//新生成的结点存放x
newnode->data = x;
newnode->next = NULL;
if (ISEmpty(p))//原来的队列为空
{
p->phead = newnode;
p->tail = newnode;
}
else
{
p->tail->next = newnode;
p->tail = newnode;
}
p->size++;
}
void QPop(Queue* p)//出队
{
assert(p);
if (ISEmpty(p))
{
printf("已空!\n");
return;
}
else if (p->phead->next == NULL)
{
free(p->phead);
p->phead = p->tail = NULL;
p->size = 0;
}
else
{
QNode* second = p->phead->next;
free(p->phead);
p->phead = second;
p->size--;
}
}
ElemType QFront(Queue* p)//获取队头元素
{
assert(p);
assert(!ISEmpty(p));
return p->phead->data;
}
ElemType QBack(Queue* p)//获取队尾元素
{
assert(p);
assert(!ISEmpty(p));
return p->tail->data;
}
//Test.c
#include"BinaryTree.h"
int main()
{
BTNode* root = CreateTree();
// 12
// / \
// 39 46
// / \ \
// 87 66 53
//
//
printf("层序遍历结果:");
LevelOrder(root);
printf("\n");
if (BTreeComplete(root))
printf("是完全二叉树!\n");
else
printf("不是完全二叉树!\n");
return 0;
}