(一)顺序结构创建二叉树

#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]);    //值获取非空数据
}
函数实现代码

相关文章: