树与二叉树

树与二叉树

非线性结构:一对多关系。

概念

  1. 度数: 节点的孩子数量,书的度数=节点中最大度数;
  2. 层次: 节点在树的第几层(根节点层数=1);
  3. 高度/深度: 最大层数;
  4. 路径长度=从root到该节点的路径边数;
  5. 森林= n棵互不相交的树(森林+root=一棵树);

二叉树

定义: 所有节点只有最多两个孩子的树。

性质:

1.  严格区分左右孩子(即使只有1个孩子);
2.  第i层上的 节点最多为 2^(i-1)个;(根节点层数=1)
3.  深度为n的二叉树的最多节点数=2^n - 1 个节点;(每个非叶子节点都有2个孩子,即满二叉树)
4.  叶子树 = 度数为2的节点数+1;
5.  完全二叉树: 
    ① 度数小于2的节点在最下面2层;
    ② 最下面一层叶子集中在最左边。

二叉树的储存

也是代码实现创建二叉树的原理

完全二叉树编号方式从上到下,从左到右编号,root=1;

假设节点数为 n, 某节点编号 i

   -   当i>1, 不是根节点,该节点有父节点。 该节点的编号是i/2;
   -   当 2*i<=n时, 有左孩子。编号为2*i; 否则,无孩子,该节点为叶子;
   -   当 2*i+1 <=n, 有右孩子。编号为2*i+1; 否则,无孩子,为叶子;

二叉树的实现,一般采用链式

//bitree.h  完全二叉树
#ifndef _BI_TREE_H
#define _BI_TREE_H

#include <string.h>
#include <strings.h>

typedef  int data_t;
typedef  int bool;

typedef struct node_t{
    data_t data;
    struct node_t *lchild, *rchild;
}bitree_t;

//i是二叉树的起始编号,n是要创建的二叉树节点数
bitree_t* bitree_create(int i, int n);

//遍历二叉树的三种方法
void bitree_DLR(bitree_t *);
void bitree_LDR(bitree_t *);
void bitree_LRD(bitree_t *);

//使用队列方式  逐层遍历
void bitree_queueShow(bitree_t*);
//删除
bool bitree_destroy(bitree_t*);
#endif
//bitree.c
#include <stdio.h>
#include <stdlib.h>
#include "bitree.h"
#include "linkqueue.h"  //用于使用队列方式遍历二叉树

bitree_t* bitree_create(int i, int n)
{
    bitree_t* root = (bitree_t*) malloc (sizeof(bitree_t) );
    if(NULL == root)
    {
        printf("Err: Create: malloc for root failed.\n");
        return NULL;
    }
    bzero(root, sizeof(bitree_t));

    root->data = i;

    if( 2*i <= n)   //2*i<n---有左孩子,其编号就是2×i
    {
        root->lchild = bitree_create(2*i, n);
    }else{  //否则没有左孩子,本身就是叶子节点
        root->lchild = NULL;
    }

    if(2*i + 1 <=n) //2*i+1 <=n ---有右孩子,编号就是2*i+1
    {
        root->rchild = bitree_create(2*i + 1, n);
    }else{
        root->rchild = NULL;
    }

    return root;
}

//遍历二叉树的三种方法
//先序遍历-递归调用
void bitree_DLR(bitree_t *root)
{
    //当访问的二叉树为空时,结束操作
    if(NULL == root)
    {
        return;
    }
    //先访问当前root节点
    printf("%d,", root->data);
    //再访问lchild
    bitree_DLR(root->lchild);
    //最后访问rchild
    bitree_DLR(root->rchild);
}

//中序遍历
void bitree_LDR(bitree_t *root)
{
    if(NULL == root)
    {
        return;
    }
    //lchild
    bitree_DLR(root->lchild);
    //root
    printf("%d,", root->data);
    //rchild
    bitree_LDR(root->rchild);
}

void bitree_LRD(bitree_t *root)
{
    if(NULL == root)
    {
        return;
    }
    //lchild
    bitree_LDR(root->lchild);
    //rchild
    bitree_LDR(root->rchild);
    //root
    printf("%d,", root->data);

}

//使用队列方式 按照编号 逐层遍历
//这里需要先创建好队列数据结构,才能使用
void bitree_queueShow(bitree_t*root)
{
    linkqueue_t* p = linkqueue_create();
    if(NULL == p)
    {
        printf("Err: Queueshow(): malloc for temp linkqueue_t* failed.\n");
        return;
    }

    if(NULL == root)
    {
        printf("Warning: Tree is empty.\n");
        return;
    }

    linkqueue_en(p, root);  //将root装入队列

    //当队列不为空时,输出队头保存的节点
    //并将该节点的孩子插入队尾
    //最后将队头节点弹出
    while(linkqueue_isEmpty(p) != TRUE)
    {
        linkqueue_en(root->lchild);
        linkqueue_en(root->rchild);
        printf("%d,", *(linkqueue_pop(p)) );
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MichaelJay2015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值