文章目录
二叉树的定义
一个有穷的节点集合
二叉树的特征
- 每个节点最多只有两棵子树
- 每棵子树有左右之分,其次序不能颠倒,是有序数
二叉搜索树
定义:一棵二叉树,可以为空;如果不为空,满足以下性质:
- 非空左子树的所有值小于其根节点的键值
- 非空右子树的所有值大于其根节点的键值
- 左右子树都是搜索二叉树
平衡二叉树
空树或者任一节点左、右子树高度差的绝对值不超过1
二叉树的重要性质
- 在二叉树的第i层上至多有 2^(i-1)个节点
- 深度为k的二叉树上至多含有2^k-1(k>=1)个节点
- 对任意一棵二叉树,若它含有n0个叶子节点、n2个度为2的节点,则必存在n0 = n2+1
- 具有 n 个结点的完全二叉树的深度为 [ log2n]+1 ([ log2n]:表示以2为底,对n取对数,并向下取整)
- 若对含 n 个结点的完全二叉树从上到下且从左至右进行 1 至 n 的编号,则对完全二叉树中任意一个编号为 i 的结点:
(1) 若 i=1,则该结点是二叉树的根,无双亲;否则,编号为 [i/2] 的结点为其双亲结点;
(2) 若 2i>n,则该结点无左孩子, 否则,编号为 2i 的结点为其左孩子结点;
(3) 若 2i+1>n,则该结点无右孩子结点,否则,编号为2i+1 的结点为其右孩子结点。
二叉树的创建
Node * CreatBiTree() {
//先序创建二叉树
char ch;
scanf("%c", &ch);
if (ch=='#')
{
return NULL;
}
else {
Node *T = (Node *)malloc(sizeof(Node));
T->data = ch;
T->lchild = CreatBiTree();
T->rchild = CreatBiTree();
return T;
}
}
二叉树的先序遍历
void PreOrderTraverse(Node *T) {
//先序遍历
if (T)
{
printf("%2c ", T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
二叉树的中序遍历
void MidOrderTraverse(Node *T) {
//中序遍历
if (T)
{
MidOrderTraverse(T->lchild);
printf("%2c ", T->data);
MidOrderTraverse(T->rchild);
}
}
二叉树的后序遍历
void LaOrderTraverse(Node *T) {
//后序遍历
if (T)
{
LaOrderTraverse(T->lchild);
LaOrderTraverse(T->rchild);
printf("%2c ", T->data);
}
}
二叉树的层序遍历
/**
层序遍历要结合队列的出队,入队来写*/
void LevelOrderTraversal(Queue *q, struct node *root) {
//层次遍历,边进边出
struct node *temp;
Push(q, root);
while (!empty(q))
{
temp = Pop(q);
printf("%2c", temp->data);
if (temp->lchild)
{
Push(q, temp->lchild);
}
if (temp->rchild)
{
Push(q, temp->rchild);
}
}
二叉树的深度
int countDepth(Node *t) {
//求二叉树的深度
if (t==NULL)
{
return 0;
}
else if (t->lchild == NULL && t->rchild == NULL) {
return 1;
}
else {
int depth1 = countDepth(t->lchild) ;
int depth2 = countDepth(t->rchild) ;
return depth1 > depth2 ? depth1 + 1 : depth2 + 1;
}
}
二叉树的节点数目
int countNode(Queue *q, struct node *root) {
//通过对队列的遍历求节点数目
struct node *temp;
Push(q, root);
int num = 0;
while (!empty(q))
{
temp = Pop(q);
num++;
if (temp->lchild)
{
Push(q, temp->lchild);
}
if (temp->rchild)
{
Push(q, temp->rchild);
}
}
return num;
}
复制二叉树
//二叉树的复制
Node *CopyTree(Node *T) {
Node *t = (Node *)malloc(sizeof(Node));
if (T == NULL) {
t = NULL;
return t;
}
else {
t->data = T->data;
t->lchild = CopyTree(T->lchild);
t->rchild = CopyTree(T->rchild);
return t;
}
}
二叉树叶子节点的数目
int CountLeaf(Node *t) {//叶子节点的数目
static int num = 0;
if (t == NULL) {
return 0;
}
else {
if (t->lchild==NULL&&t->rchild==NULL)
{
num++;
}
CountLeaf(t->lchild);
CountLeaf(t->rchild);
}
return num;
}
//统计叶子节点
void CountLeaf(Node *T) {
if (T == NULL) {
return ;
}
else {
if (T->lchild == NULL && T->rchild == NULL) {
printf("%2c ", T->data);
}
CountLeaf(T->lchild);
CountLeaf(T->rchild);
}
}
全部代码
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<malloc.h>
#define max 100
typedef struct node {
char data;
struct node *lchild, *rchild;
}Node;
typedef struct queue {
struct node * num[max];
int front;
int rear;
}Queue;
Queue * initilize() {
Queue *q = (Queue*)malloc(sizeof(Queue));
q->front = 0;
q->rear = 0;
return q;//初始化队列
}
void Push(Queue *q, struct node *root) {
q->num[++q->rear] = root;//入队
}
struct node *Pop(Queue *q) {
return q->num[++q->front];//出队
}
bool empty(Queue *q) {
return q->front == q->rear;//判断队列是否为空
}
Node * CreatBiTree() {
//先序创建二叉树
char ch;
scanf("%c", &ch);
if (ch=='#')
{
return NULL;
}
else {
Node *T = (Node *)malloc(sizeof(Node));
T->data = ch;
T->lchild = CreatBiTree();
T->rchild = CreatBiTree();
return T;
}
}
void PreOrderTraverse(Node *T) {
//先序遍历
if (T)
{
printf("%2c ", T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void MidOrderTraverse(Node *T) {
//中序遍历
if (T)
{
MidOrderTraverse(T->lchild);
printf("%2c ", T->data);
MidOrderTraverse(T->rchild);
}
}
void LaOrderTraverse(Node *T) {
//后序遍历
if (T)
{
LaOrderTraverse(T->lchild);
LaOrderTraverse(T->rchild);
printf("%2c ", T->data);
}
}
void LevelOrderTraversal(Queue *q, struct node *root) {
//层次遍历,边进边出
struct node *temp;
Push(q, root);
while (!empty(q))
{
temp = Pop(q);
printf("%2c", temp->data);
if (temp->lchild)
{
Push(q, temp->lchild);
}
if (temp->rchild)
{
Push(q, temp->rchild);
}
}
}
int countDepth(Node *t) {
//求二叉树的深度
if (t==NULL)
{
return 0;
}
else if (t->lchild == NULL && t->rchild == NULL) {
return 1;
}
else {
int depth1 = countDepth(t->lchild) ;
int depth2 = countDepth(t->rchild) ;
return depth1 > depth2 ? depth1 + 1 : depth2 + 1;
}
}
int countNode(Queue *q, struct node *root) {
//通过对队列的遍历求节点数目
struct node *temp;
Push(q, root);
int num = 0;
while (!empty(q))
{
temp = Pop(q);
num++;
if (temp->lchild)
{
Push(q, temp->lchild);
}
if (temp->rchild)
{
Push(q, temp->rchild);
}
}
return num;
}
int CountLeaf(Node *t) {//叶子节点的数目
static int num = 0;
if (t == NULL) {
return 0;
}
else {
if (t->lchild==NULL&&t->rchild==NULL)
{
num++;
}
CountLeaf(t->lchild);
CountLeaf(t->rchild);
}
return num;
}
int main() {
printf("先序遍历输入:");
Node *T = CreatBiTree();
printf("先序遍历输出:\n");
PreOrderTraverse(T);
printf("\n");
printf("中序遍历输出:\n");
MidOrderTraverse(T);
printf("\n");
printf("后序遍历输出:\n");
LaOrderTraverse(T);
printf("\n");
printf("层次遍历输出:\n");
Queue *q = initilize();
LevelOrderTraversal(q, T);
printf("\n");
printf("树的深度为:%d\n", countDepth(T));
printf("节点的数目为:%d\n", countNode(q,T));
printf("叶子节点的数目为:%d\n", CountLeaf(T));
}