(一)顺序结构创建二叉树
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 //存储空间初始分配量
#define MAX_TREE_SIZE 100 //二叉树的最大结点数
typedef char TElemType;
typedef int Status;
typedef TElemType SqBiTree[MAX_TREE_SIZE]; //定义顺序二叉树的结构
typedef struct
{
int level, order; //结点的层,本层的序号
}Position;
TElemType Nil = '^'; //设置结点以^为空
Status InitBiTree(SqBiTree T); //构造空二叉树T,因为T是固定数组,不会改变,故不需要&
Status CreateBiTree(SqBiTree T);//按照层序次序输入二叉树中结点的值,构造顺序存储的二叉树
Status BiTreeEmpty(SqBiTree T);//判断二叉树是否为空
int BiTreeDepth(SqBiTree T);//获取二叉树的深度
Status Root(SqBiTree T, TElemType* e);//返回根节点数据
TElemType Value(SqBiTree T, Position e);//获取具体位置的结点值
Status Assign(SqBiTree T, Position e, TElemType value);//对某个叶子结点赋值
TElemType Parent(SqBiTree T, TElemType e);//根据元素,获取其双亲结点的值
TElemType LeftChild(SqBiTree T, TElemType e);//返回结点的左孩子
TElemType RightChild(SqBiTree T, TElemType e);//返回结点的右孩子
TElemType LeftSibling(SqBiTree T, TElemType e);//返回结点的左兄弟
TElemType RightSibling(SqBiTree T, TElemType e);//返回结点的右兄弟
void PreOrderTraverse(SqBiTree T, int e);//开始进行前序遍历
void InOrderTraverse(SqBiTree T, int e);//开始进行中序遍历
void PostOrderTraverse(SqBiTree T, int e);//开始进行后序遍历
void LevelOrderTraverse(SqBiTree T);//开始进行层序遍历
![]()
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 //存储空间初始分配量
#define MAX_TREE_SIZE 100 //二叉树的最大结点数
typedef char TElemType;
typedef int Status;
typedef TElemType SqBiTree[MAX_TREE_SIZE]; //定义顺序二叉树的结构
typedef struct
{
int level, order; //结点的层,本层的序号
}Position;
TElemType Nil = '^'; //设置结点以^为空
//构造空二叉树T,因为T是固定数组,不会改变,故不需要&
Status InitBiTree(SqBiTree T)
{
int i;
for (i = 0; i < MAX_TREE_SIZE; i++)
T[i] = Nil;
return OK;
}
//按照层序次序输入二叉树中结点的值,构造顺序存储的二叉树T
Status CreateBiTree(SqBiTree T)
{
int i = 0;
char ch;
printf("please enter value for node(^ is Nil,# exit) number must <= %d:\n",MAX_TREE_SIZE);
scanf("%c", &ch);
while (ch!='#')
{
T[i++] = ch;
if (i != 0 && T[i] != Nil &&T[(i + 1) / 2 - 1] == Nil) //不为根节点,自己又不为空,父节点又不存在,一定是错的
{
printf("exist a node not parents node:%c",T[i]);
exit(ERROR);
}
scanf("%c", &ch);
}
//将后面的结点全部置为空:是为了防止使用时创建两次二叉树,出现数据冗余
while (i<MAX_TREE_SIZE)
{
T[i++] = Nil; //将空值赋给T后面的结点
}
return OK;
}
#define ClearBiTree InitBiTree //在顺序存储结构中,两者是一致的
//判断二叉树是否为空
Status BiTreeEmpty(SqBiTree T)
{
if (T[0] == Nil)
return TRUE;
return FALSE;
}
//获取二叉树的深度
int BiTreeDepth(SqBiTree T)
{
int i, j=-1;
for (i = MAX_TREE_SIZE-1; i >= 0; i--) //获取最后一个结点
if (T[i] != Nil)
break;
//根据pow判断深度
i++; //获取从1开始的二叉树,而不是以0开始,方便下面计算
do
{
j++;
} while (i>=pow(2,j));
return j;
}
//返回根节点数据
Status Root(SqBiTree T, TElemType* e)
{
if (BiTreeEmpty(T))
return ERROR;
*e = T[0];
return OK;
}
//获取具体位置的结点值
TElemType Value(SqBiTree T, Position e)
{
return T[(int)pow(2,e.level-1)-2+e.order];
}
//对某个叶子结点赋值
Status Assign(SqBiTree T, Position e, TElemType value)
{
//先将e转换Wie一维数组的下标
int index = (int)pow(2, e.level - 1) - 2 + e.order;
//判断其双亲是否存在
if (index != 0 && T[(index + 1) / 2 - 1] == Nil)
return ERROR;
//若是我们赋值为空,但是其子节点存在,也返回空
if (value == Nil && (T[index * 2 + 1] != Nil || T[index * 2 + 2] != Nil))
return ERROR;
T[index] = value;
return OK;
}
//根据元素,获取其双亲结点的值
TElemType Parent(SqBiTree T, TElemType e)
{
int i;
//若是空树
if (T[0] == Nil)
return Nil;
for (i = 1; i < MAX_TREE_SIZE; i++) //注意这里从1开始,若是出现在头结点,会直接在下面返回Nil
if (T[i] == e) //找到该结点
return T[(i + 1) / 2 - 1];
return Nil;
}
//返回结点的左孩子
TElemType LeftChild(SqBiTree T, TElemType e)
{
int i;
//若是空树
if (T[0] == Nil)
return Nil;
for (i = 1; i < MAX_TREE_SIZE; i++) //注意这里从1开始,若是出现在头结点,会直接在下面返回Nil
if (T[i] == e) //找到该结点
return T[2*i+1];
return Nil;
}
//返回结点的右孩子
TElemType RightChild(SqBiTree T, TElemType e)
{
int i;
//若是空树
if (T[0] == Nil)
return Nil;
for (i = 1; i < MAX_TREE_SIZE; i++) //注意这里从1开始,若是出现在头结点,会直接在下面返回Nil
if (T[i] == e) //找到该结点
return T[2 * i + 2];
return Nil;
}
//返回结点的左兄弟
TElemType LeftSibling(SqBiTree T, TElemType e)
{
int i;
//若是空树
if (T[0] == Nil)
return Nil;
for (i = 1; i < MAX_TREE_SIZE; i++) //注意这里从1开始,若是出现在头结点,会直接在下面返回Nil
if (T[i] == e&&i%2==0) //找到右节点
return T[i-1];
return Nil;
}
//返回结点的右兄弟
TElemType RightSibling(SqBiTree T, TElemType e)
{
int i;
//若是空树
if (T[0] == Nil)
return Nil;
for (i = 1; i < MAX_TREE_SIZE; i++) //注意这里从1开始,若是出现在头结点,会直接在下面返回Nil
if (T[i] == e&&i % 2 == 1) //找到左节点
return T[i + 1];
return Nil;
}
//开始进行前序遍历
void PreOrderTraverse(SqBiTree T,int e)
{
if (T&&e<MAX_TREE_SIZE)
{
if (T[e] != Nil)
printf("%c", T[e]);
PreOrderTraverse(T, 2 * e + 1);
PreOrderTraverse(T, 2 * e + 2);
}
}
//开始进行中序遍历
void InOrderTraverse(SqBiTree T, int e)
{
if (T&&e<MAX_TREE_SIZE)
{
InOrderTraverse(T, 2 * e + 1);
if (T[e] != Nil)
printf("%c", T[e]);
InOrderTraverse(T, 2 * e + 2);
}
}
//开始进行后序遍历
void PostOrderTraverse(SqBiTree T, int e)
{
if (T&&e<MAX_TREE_SIZE)
{
PostOrderTraverse(T, 2 * e + 1);
PostOrderTraverse(T, 2 * e + 2);
if (T[e]!=Nil)
printf("%c", T[e]);
}
}
//开始进行层序遍历
void LevelOrderTraverse(SqBiTree T)
{
int i = MAX_TREE_SIZE - 1;
int j;
while (T[i] == Nil)
i--;
for (j = 0; j <= i; j++)
if (T[j] != Nil)
printf("%c", T[j]); //值获取非空数据
}
函数实现代码