二叉树

851 阅读5分钟

二叉树

  • 了解树和二叉树的相关定义
  • 二叉树顺序存储的定义和相关操作的实现
  • 二叉树顺序存储下的前序/中序/后序/层序遍历
  • 二叉树链式存储下相关操作以及遍历实现

了解树和二叉树的相关定义

树结构

树结构中的高度、深度和层数

节点: 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);
}