• C语言数据库-二叉树


    一、定义

    二叉树在图论中是这样定义的:二叉树是一个连通的无环图,并且每一个顶点的度不大于3。有根二叉树还要满足根结点的度不大于2。有了根结点之后,每个顶点定义了唯一的父结点,和最多2个子结点。然而,没有足够的信息来区分左结点和右结点。如果不考虑连通性,允许图中有多个连通分量,这样的结构叫做森林。

    二、基本概念

    二叉树是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态:
    (1)空二叉树——如图(a);
    (2)只有一个根结点的二叉树——如图(b);
    (3)只有左子树——如图(c);
    (4)只有右子树——如图(d);
    (5)完全二叉树——如图(e)。
    注意:尽管二叉树与树有许多相似之处,但二叉树不是树的特殊情形。[1] 

    三、类型

    (1)完全二叉树——若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树
    (2)满二叉树——除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。
    (3)平衡二叉树——平衡二叉树又被称为AVL树(区别于AVL算法),它是一棵二叉排序树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。[2] 

    四、相关术语

    树的结点:包含一个数据元素及若干指向子树的分支;
    孩子结点:结点的子树的根称为该结点的孩子;
    双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;
    兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;
    祖先结点: 从根到该结点的所经分支上的所有结点子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙
    结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;
    树的深度:树中最大的结点层
    结点的度:结点子树的个数
    树的度: 树中最大的结点度。
    叶子结点:也叫终端结点,是度为 0 的结点;
    分枝结点:度不为0的结点;
    有序树:子树有序的树,如:家族树;
    无序树:不考虑子树的顺序;[3]
    五、代码实现
      1   1 //  main.c
      2   2 
      3   3 //  C语言-二叉树
      4   4 
      5   5 //
      6   6 
      7   7 //  Created by rimi on 2017/5/24.
      8   8 
      9   9 //  Copyright © 2017年 rimi. All rights reserved.
     10 
     11  15 #include <stdio.h>
     12  16 
     13  17 #include <stdlib.h>
     14  23 struct TreeNode {
     15  24 
     16  25     char data;
     17  26 
     18  27     struct TreeNode * left;
     19  28 
     20  29     struct TreeNode * right;
     21  30 
     22  31 };
     23  35 // 创建树
     24  36 
     25  37 struct TreeNode * createTree();
     26  38 
     27  39 // 先序遍历
     28  40 
     29  41 void preTraverse(struct TreeNode * root);
     30  42 
     31  43 // 中序遍历
     32  44 
     33  45 void centerTraverse(struct TreeNode * root);
     34  46 
     35  47 // 后序遍历
     36  48 
     37  49 void backTraverse(struct TreeNode * root);
     38  53 int main(int argc, const char * argv[]) {
     39  54 
     40  55   //  preTraverse(createTree());
     41  56 
     42  57     centerTraverse(createTree());
     43  58 
     44  59    // backTraverse(createTree());
     45  60 
     46  61     return 0;
     47  62 
     48  63 }
     49  64 
     50  65 // 创建树
     51  66 
     52  67 struct TreeNode * createTree(){
     53  71     struct TreeNode * pa = (struct TreeNode *)malloc(sizeof(struct TreeNode));
     54  72 
     55  73     struct TreeNode * pb = (struct TreeNode *)malloc(sizeof(struct TreeNode));
     56  74 
     57  75     struct TreeNode * pc = (struct TreeNode *)malloc(sizeof(struct TreeNode));
     58  76 
     59  77     struct TreeNode * pd = (struct TreeNode *)malloc(sizeof(struct TreeNode));
     60  78 
     61  79     struct TreeNode * pe = (struct TreeNode *)malloc(sizeof(struct TreeNode));
     62  80 
     63  81     struct TreeNode * pf = (struct TreeNode *)malloc(sizeof(struct TreeNode));
     64  82 
     65  83     struct TreeNode * pg = (struct TreeNode *)malloc(sizeof(struct TreeNode));
     66  84 
     67  85     pa->data = 'A';
     68  86 
     69  87     pb->data = 'B';
     70  88 
     71  89     pc->data = 'C';
     72  90 
     73  91     pd->data = 'D';
     74  92 
     75  93     pe->data = 'E';
     76  94 
     77  95     pf->data = 'F';
     78  96 
     79  97     pg->data = 'G';
     80  98 
     81  99     
     82 100 
     83 101     pa->left = pb;
     84 103     pa->right = pc;
     85 
     86 107     pb->left = pd;
     87 109     pb->right = NULL;
     88 
     89 
     90 113     pc->left = pe;
     91 115     pc->right = pf;
     92 
     93 119     pd->left = NULL;
     94 120 
     95 121     pd->right = pg;
     96 
     97 125     pe->left = NULL;
     98 126 
     99 127     pe->right = NULL;
    100 
    101 131     pf->left = NULL;
    102 132 
    103 133     pf->right = NULL;
    104 
    105 137     pg->left = NULL;
    106 138 
    107 139     pg->right = NULL;
    108 143     return pa;
    109 144 
    110 145 }
    111 146 
    112 147 // 先序遍历
    113 148 
    114 149 void preTraverse(struct TreeNode * root){
    115 150 
    116 151     if (root != NULL) {
    117 152 
    118 153         printf("%c
    ", root->data);
    119 154 
    120 155         preTraverse(root->left);
    121 156 
    122 157         preTraverse(root->right);
    123 158 
    124 159     }
    125 160 
    126 161 }
    127 162 
    128 163 // 中序遍历
    129 164 
    130 165 void centerTraverse(struct TreeNode * root){
    131 166 
    132 167     if(root !=NULL) {
    133 168 
    134 169         centerTraverse(root ->left);
    135 173         printf("%c 
    ",root ->data);
    136 174
    137 177        centerTraverse(root->right);
    138 178 
    139 183     }
    140 184 
    141 185 }
    142 187 // 后序遍历
    143 188 
    144 189 void backTraverse(struct TreeNode * root){
    145 190 
    146 191     if(root !=NULL){
    147 192 
    148 193     backTraverse(root ->left);
    149 194 
    150 195     backTraverse(root ->right);
    151 196 
    152 197     printf("%c 
    ",root ->data);
    153 198 
    154 199     }
    155 203 }
  • 相关阅读:
    类和迭代器
    使用委托调用函数
    自定义类和集合
    带函数的参数返回函数的最大值
    使用程序调试输出窗口
    自定义类
    类和结构
    全局参数
    带参数的函数返回数组之和
    IS运算符
  • 原文地址:https://www.cnblogs.com/sbj-dawn/p/6906015.html
Copyright © 2020-2023  润新知