数据结构-树

文章介绍了树的基本概念和性质,包括根节点、度数、层数等。接着详细讲解了二叉树,特别是满二叉树和完全二叉树的定义。在完全二叉树中,提出了编号机制和存储结构,以及先序、中序和后序遍历的方法。最后,给出了创建和遍历完全二叉树的C语言实现。
摘要由CSDN通过智能技术生成

1.1 树的概念与性质

树的概念:树(Tree)是n(n>=0)个节点的有限集合T

它满足两个条件:

有且仅有一个特定的节点,被称之为根节点(Root)

其余的节点可以分为m(m>=0)个互不相交的有限集合,其中每一个集合又是一棵树,并称为根的子树

度数:一个节点的子树个数称之为该节点的度数,一棵树的度数是指该树中节点的最大度数

层数:节点的层数等于父节点的层数加一,根节点的层数定义为一。一个树的层数是指该树中节点的最大层数

边数:从根节点k1遍历到此节点Kj,并满足ki是ki+1的父节点,就称为一条从k1到kj的路径,路径的长度为j-1,即路径的边数。

叶子(叶节点):没有子节点的节点

1.2 二叉树的概念和性质

二叉树的定义:二叉树是树的一种,它满足树的基本性质,但二叉树和普通树又有所不同,二叉树要求每个节点至多只能拥有两个子节点,并将子节点严格区分为左孩子和右孩子,即使只有一个子节点也要区分左右。

满二叉树:除叶节点以外,度数都为2的二叉树,且叶节点都在最底层

完全二叉树:如果二叉树除去最后一层节点以外为满二叉树,且最后一层的节点从左到右依次分布,且不存在只有右子树的节点,则称该二叉树为完全二叉树。

1.3 完全二叉树的编号机制

如果根节点的编号为1,则之后的每个节点从上到下,从左到右依次编号递增,若节点的总数为n。

某一个节点的编号为i,则可以判断这个节点是否存在左右子树,并且可以得到左右子树的编号。

如果2 * i 如果2 * i + 1

1.4 完全二叉树的存储结构

顺序存储:为了能够清楚每个节点之间的关系,所以需要将没有左右子树的位置预留出来,这样做十分浪费空间,所以我们一般不考虑树的顺序存储。

链式存储:用两个指针分别存储左子树和右子树的地址

1.5 完全二叉树的遍历

先序遍历:先遍历根节点,再遍历左节点,再遍历右节点 —— 根左右

中序遍历:先遍历左节点,再遍历根节点,再遍历右节点 —— 左根右

后序遍历:先遍历左节点,再遍历右节点,再遍历根节点 —— 左右根

1.6 完全二叉树的创建和遍历

1.6.1 bitree.h

#ifndef _BITREE_H
#define _BITREE_H_

#include<stdio.h>
#include<stdlib.h>

typedef struct node{
    int id;     //数据 —— 编号
    struct node* lchild;  //保存左子树的地址
    struct node* rchild; //保存右子树的地址
}bitree;

bitree* comBitreeCreate(int n, int i);
void bitreePreOrder(bitree *root);
void bitreeInOrder(bitree *root);
void bitreePostOrder(bitree *root);

#endif

1.6.2 bitree.c

#include"bitree.h"

//创建一个完全二叉树
//n:结点的总个数
//i :结点的编号 —— i初始值为1
bitree* comBitreeCreate(int n, int i){
    bitree *root = (bitree *)malloc(sizeof(bitree));
    root->id = i;

    //判断左子树是否存在
    if(2 * i <= n){
        root->lchild = comBitreeCreate(n, 2 * i);
    }else{
        root->lchild = NULL;
    }

    //判断右子树是否存在
    if(2 * i + 1 <= n){
        root->rchild = comBitreeCreate(n, 2 * i + 1);
    }else{
        root->rchild = NULL;
    }
    return root;
}

//先序遍历 —— 根左右
void bitreePreOrder(bitree *root){
    printf("%d ",root->id);
    if(root->lchild != NULL){
        bitreePreOrder(root->lchild);
    }
    if(root->rchild != NULL){
        bitreePreOrder(root->rchild);
    }
    return ;
}

//中序遍历 —— 左根右
void bitreeInOrder(bitree *root){
    if(root->lchild != NULL){
        bitreePreOrder(root->lchild);
    }
    printf("%d ",root->id);
    if(root->rchild != NULL){
        bitreePreOrder(root->rchild);
    }
    return ;
}

//后序遍历 —— 左右根
void bitreePostOrder(bitree *root){
    if(root->lchild != NULL){
        bitreePreOrder(root->lchild);
    }
    if(root->rchild != NULL){
        bitreePreOrder(root->rchild);
    }
    printf("%d ",root->id);
    return ;
}

1.6.3 main.c

#include"bitree.h"
int main(int argc, char const *argv[]){
    bitree *root = comBitreeCreate(8, 1);
    //先序遍历
    printf("PreOrder : ");
    bitreePreOrder(root);
    putchar(10);

    //中序遍历
    printf("InOrder : ");
    bitreeInOrder(root);
    putchar(10);

    //后序遍历
    printf("PostOrder : ");
    bitreePostOrder(root);
    putchar(10);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值