树是递归定义的:树是n(非负整数)个结点的有限集。n = 0 时为空树。在任意一棵非空树中:
- 有且仅有一个特定的称为根的结点
- 当n>1时,其余结点可分为m(m > 0)个互不相交的有限集,其中每一个集合本身又是一棵树,并且称为根的子树。
二叉树
- 每个子结点不超过两个
- 左右结点是有顺序的
特殊二叉树
-
斜树
只有左子树或者只有右子树,分别对应左斜和右斜
-
满二叉树
所有分支结点都有左子树和右子树,且叶子结点在同一层
-
完全二叉树
对棵的n个结点按层进行编号,编号为i的结点与同样深度的满二叉树的位置相同。也就是自上而下,自左向右按顺序排号,一个都不能跳过。
二叉树的性质
序号 | 0层开始(根结点深度为0) | 1层开始(根结点深度为1) |
---|---|---|
1 | 第n层至多有 2 n 2^n 2n个结点 | 第n层至多有 2 n − 1 2^{n - 1} 2n−1个结点 |
2 | 深度为k的二叉树至多有 2 k + 1 2^{k +1} 2k+1个结点 | 深度为k的二叉树至多有 2 k − 1 2^{k - 1} 2k−1个结点 |
3 | 叶子结点数 = 度为2的结点数+1 | 叶子结点数 = 度为2的结点数+1 |
4 | 具有n个结点的完全二叉树的深度为 [log2n](以2为底n的对数向下取整) | 具有n个结点的完全二叉树的深度为 [log2n]+1(以2为底n的对数向下取整) |
对于一个结点i和总结点n。
- i = 1,其为根
- 2i > n,叶子结点
- 2i = n,最后一个结点
- 2i < n,内部结点
头文件head.h
#ifndef HEAD_H
#define HEAD_H
typedef char TElementType;
typedef struct Node* BiThrTree;
typedef struct Node{
TElementType data;
BiThrTree lchild;
BiThrTree rchild;
}BiThrNode;
/*建立二叉树*/
BiThrTree CreateBiThrTree(void);
/*释放内存*/
void FreeBiThrTree(BiThrTree T);
/*前序遍历*/
void PreOrderTraverse(BiThrTree T);
/*中序遍历*/
void InOrderTraverse(BiThrTree T);
/*后序遍历*/
void PostOrderTraverse(BiThrTree T);
#endif
操作集operation.c
#include "head.h"
#include <stdio.h>
#include <stdlib.h>
/*
功能:建立一棵二叉树
返回:头结点指针
*/
BiThrTree CreateBiThrTree(void)
{
BiThrTree T;
TElementType ch;
scanf("%c", &ch);
if (ch == '#')
{
return NULL;
}
else
{
T = (BiThrTree)malloc(sizeof(BiThrNode));
if (T == NULL)
{
printf("out of space!\n");
exit(EXIT_FAILURE);
}
T->data = ch;
T->lchild = CreateBiThrTree();
T->rchild = CreateBiThrTree();
}
return T;
}
/*
功能:释放树
参数:树的头结点指针
确保没有子树时,释放该结点,所以可以用后序遍历来实现操作
*/
void FreeBiThrTree(BiThrTree T)
{
if (T == NULL)
{
return ;
}
FreeBiThrTree(T->lchild);
FreeBiThrTree(T->rchild);
free(T);
}
/*
功能:前序遍历二叉树
参数:二叉树头结点指针
*/
void PreOrderTraverse(BiThrTree T)
{
if (T == NULL)
{
printf("#");
return ;
}
printf("%c", T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
/*
功能:中序遍历二叉树
参数:二叉树头结点指针
*/
void InOrderTraverse(BiThrTree T)
{
if (T == NULL)
{
printf("#");
return ;
}
InOrderTraverse(T->lchild);
printf("%c", T->data);
InOrderTraverse(T->rchild);
}
/*
功能:后序遍历二叉树
参数:二叉树头结点指针
*/
void PostOrderTraverse(BiThrTree T)
{
if (T == NULL)
{
printf("#");
return ;
}
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c", T->data);
}
主函数main.c
#include <stdio.h>
#include <stdlib.h>
#include "head.h"
int main(void)
{
BiThrTree T = CreateBiThrTree();
/*前序*/
PreOrderTraverse(T);
printf("\n");
/*中序*/
InOrderTraverse(T);
printf("\n");
/*后序*/
PostOrderTraverse(T);
printf("\n");
FreeBiThrTree(T);
T = NULL;
return 0;
}