二叉树
- 了解树和二叉树的相关定义
- 二叉树顺序存储的定义和相关操作的实现
- 二叉树顺序存储下的前序/中序/后序/层序遍历
- 二叉树链式存储下相关操作以及遍历实现
了解树和二叉树的相关定义
树结构
树结构中的高度、深度和层数
节点: A B C... 是节点 度: 节点拥有的子树。 A的度是3,B的度是2 叶子: 度为0的节点是叶子结点或终点节点。 例如K J M 双亲节点:A是B C D的双亲节点(父母合体)。 兄弟:同属于一个双亲节点下的孩子。例如B C D是兄弟节点,E F是兄弟节点 节点高度:节点到叶子节点最长的边数。 A 的高度是3,B D 的高度是2, M的高度是0。 深度:跟节点到节点经历的边数。D 是1 层:A是一层 B C D是二层
二叉树
空树或者非空树 非空树满足条件: 除了跟节点都是两个互补相交的子集,并且每个节点有且只有两个节点【每个节点最多分两个叉,不存在度数大于2的节点】
二叉树的特性
子树有左右之分,不可以颠倒。
二叉树的五种形态
特殊二叉树 左斜数 右斜数
满二叉树
二叉树的分支节点都有左子树和右子树,并且左右的叶子都在同一层。
完全二叉树
不是完全二叉树 少了一个序号为10的叶子节点
缺少 6 7 的序号的节点
节点5 缺少了两个节点
二叉树的性质
二叉树顺序存储的定义和相关操作的实现
二叉树的存储分析
顺序存储会造成空间浪费
顺序存储适合完全二叉树
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 /* 存储空间初始分配量 */
#define MAX_TREE_SIZE 100 /* 二叉树的最大结点数 */
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int CElemType; /* 树结点的数据类型,目前暂定为整型 */
typedef CElemType SqBiTree[MAX_TREE_SIZE];/* 0号单元存储根结点 */
CElemType NilNode = 0; /*设整型以0为空 或者以 INT_MAX(65535)*/
typedef struct {
int level; // 节点层号
int order; // 序号 按照满二叉树的序号
}Position;
/*
* 1. 初始化
*/
Status InitBiTree(SqBiTree T) {
for (int i = 0; i < MAX_TREE_SIZE; i++) {
T[i] = NilNode;
}
return OK;
}
/*
* 2. 创建二叉树
*/
Status CreateBiTree(SqBiTree T) {
int i = 0;
while (i < 10) {
T[i] = i + 1;
printf("%d ", T[i]);
//结点不为空,且无双亲结点 父亲节点index = (i+1) / 2 -1
if (i != 0 && T[ (i+1) / 2 -1] == NilNode && T[i] == NilNode) {
printf("出现无双亲的非根结点%d\n",T[i]);
exit(ERROR);
}
i++;
}
while (i < MAX_TREE_SIZE) {
T[i] = NilNode;
i++;
}
return OK;
}
/*
* 3. 清空二叉树
*/
#define ClearBiTree InitBiTree
/*
* 4. 二叉树判空
*/
Status BiTreeEmpty(SqBiTree T) {
if (T[0] == NilNode) {
return TRUE;
}
return FALSE;
}
/*
* 5. 二叉树的深度
*/
int BiTreeDepth(SqBiTree T) {
int j = -1;
int i;
// 找到最后一个节点
for (i = MAX_TREE_SIZE - 1; i >= 0; i--) {
if (T[i] != NilNode) {
break;
}
}
/*
* 找到最后一个节点所在的层数
* 1 2^0
* 2 3 2^1
* 4 5 6 7 2^2
* powl(2, j) 计算层数的最大索引
*/
do {
j++;
} while (powl(2, j) <= i);
return j;
}
/*
* 6. 处于e节点位置的值
*/
CElemType Value(SqBiTree T, Position e) {
printf("层: %d\n", (int)powl(2, e.level - 1));
printf("序号:%d\n", e.order);
return T[(int)powl(2, e.level - 1) + e.order - 2];
}
/*
* 7. 修改节点的值
*/
Status Assign(SqBiTree T, Position e, CElemType value) {
int i = (powl(2, e.level - 1)) + e.order - 2;
if (value != NilNode && T[(i+1)/2 -1] == NilNode) {
return ERROR;
}
T[i] = value;
return OK;
}
二叉树顺序存储下的前序/中序/后序/层序遍历
遍历
前序遍历
A B D G H C E I F
中序遍历
G D H B A E I C F
后续遍历
层序遍历
/*
* 8. 层序遍历
*/
void LevelOrderTraverse(SqBiTree T) {
int i = MAX_TREE_SIZE - 1;
while (T[i] == NilNode) {
i--;
}
for (int j = 0; j < i; j++) {
if (T[i] != NilNode) {
printf("%d ", T[j]);
}
}
printf("\n");
}
/*
* 9. 前序遍历
*/
void PreTravese(SqBiTree T, int e) {
printf("%d ", T[e]);
// 左子树
if (T[2 * e + 1] != NilNode) {
PreTravese(T, 2 * e + 1);
}
// 右子树
if (T[2 * e + 2] != NilNode) {
PreTravese(T, 2 * e + 2);
}
}
Status PreOrderTravese(SqBiTree T) {
if (!BiTreeEmpty(T)) {
PreTravese(T, 0);
}
printf("\n");
return OK;
}
/*
* 10. 中序遍历
*/
void InTravese(SqBiTree T, int e) {
// 左子树
if (T[2 * e + 1] != NilNode) {
InTravese(T, 2 * e + 1);
}
// 根节点
printf("%d ", T[e]);
// 右子树
if (T[2 * e + 2] != NilNode) {
InTravese(T, 2 * e + 2);
}
}
Status PreInTravese(SqBiTree T) {
if (!BiTreeEmpty(T)) {
InTravese(T, 0);
}
return OK;
}
/*
* 11. 后续遍历
*/
void PostTravese(SqBiTree T, int e) {
// 左子树
if (T[2 * e + 1] != NilNode) {
PostTravese(T, 2 * e + 1);
}
// 右子树
if (T[2 * e + 2] != NilNode) {
PostTravese(T, 2 * e + 2);
}
// 根节点
printf("%d ", T[e]);
}
Status PrePostTravese(SqBiTree T) {
if (!BiTreeEmpty(T)) {
PostTravese(T, 0);
}
return OK;
}
二叉树链式存储下相关操作以及遍历实现
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
/* 存储空间初始分配量 */
#define MAXSIZE 100
/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Status;
#pragma mark--二叉树构造
int indexs = 1;
typedef char String[24]; /* 0号单元存放串的长度 */
String str;
Status StrAssign(String T,char *chars)
{
int i;
if(strlen(chars)>MAXSIZE)
return ERROR;
else
{
T[0]=strlen(chars);
for(i=1;i<=T[0];i++)
T[i]=*(chars+i-1);
return OK;
}
}
typedef char CElemType;
CElemType LinkNilNode = ' ';
typedef struct BiTNode {
CElemType data;
struct BiTNode *lchild;
struct BiTNode *rchild;
}BiTNode, *BiTree;
/*
* 1. 空二叉树
*/
Status LinkInitBiTree(BiTree *T) {
*T = NULL;
return OK;
}
/*
* 2. 创建二叉树
*/
void LinkCreateBiTree(BiTree *T) {
CElemType ch;
ch = str[indexs++];
// 空树
if (ch == '#') {
*T = NULL;
} else {
*T = (BiTree)malloc(sizeof(BiTNode));
if (*T == NULL) {
exit(OVERFLOW);
}
(*T)->data = ch;
LinkCreateBiTree(&(*T)->lchild);
LinkCreateBiTree(&(*T)->rchild);
}
}
/*
* 前序遍历
*/
void LinkPreOrderTravese(BiTree T) {
if (T == NULL) {
return;
}
printf("%c ", T->data);
LinkPreOrderTravese(T->lchild);
LinkPreOrderTravese(T->rchild);
}
/*
* 链表为空
*/
Status LinkBiTreeEmpty(BiTree T) {
if (T) {
return FALSE;
}
return TRUE;
}
/*
* 深度
*/
int LinkBiTreeDepth(BiTree T) {
int i, j;
if (LinkBiTreeEmpty(T)) {
return 0;
}
if (T->lchild) {
i = LinkBiTreeDepth(T->lchild);
} else {
i = 0;
}
if (T->rchild) {
j = LinkBiTreeDepth(T->rchild);
} else {
j = 0;
}
return MAX(i+1, j+1);
}
/*
* 中序遍历
*/
void LinkInTravese(BiTree T) {
if (T == NULL) {
return;
}
LinkInTravese(T->lchild);
printf("%c ", T->data);
LinkInTravese(T->rchild);
}
/*
* 后序遍历
*/
void LinkPostInTravese(BiTree T) {
if (T == NULL) {
return;
}
LinkInTravese(T->lchild);
LinkInTravese(T->rchild);
printf("%c ", T->data);
}