zoukankan      html  css  js  c++  java
  • 二叉树的顺序存储C+Java

    前言:

    前面有点事耽误了一阵子,本来想写完数据结构再复习Java的...还是先补完把。

    话不多说,前面我们已经学习到了数据的链式存储结构,相对于下面要讲的顺序存储结构难些。因为树是一种一对多的数据结构,由于它的特殊性

    使用顺序存储结构也可以实现。

    顺序存储二叉树:

    二叉树的顺序存储结构就是一维数组存储二叉树中的节点,并且节点的存储位置,也就是数组下标要能体现节点之间的关系,比如双亲和孩纸的关系。左右兄弟关系等。

    来看看一颗完全二叉树的顺序存储:

    将这两颗树存储到数组里面,注意下标的表示位置 

    这下子可以看出完全二叉树的优越性来了把。然而也有出现一些极端的情况,如

    这种普通的二叉树显然是对存储空间的浪费,所以遇到这种情况的二叉树,建议使用链式二叉树,我们的顺序存储二叉树适合使用在完全二叉树下

    C代码 

      1 #include <stdio.h>
      2 #include "stdlib.h"  
      3 #include "io.h"  
      4 #include "math.h" 
      5 #include "time.h" 
      6 
      7 #define MAXSIZE 100
      8 #define MAX_TREE_SIZE 100
      9 typedef int Status;        /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
     10 typedef int TElemType;  /* 树结点的数据类型,目前暂定为整型 */
     11 typedef int SqBiTree[MAX_TREE_SIZE];/* 0号单元存储根结点  */
     12 
     13 typedef struct{
     14     /* 结点的层,本层序号(按满二叉树计算) */
     15     int level,order;
     16 }Position;
     17 
     18 //假设整数0代表为空
     19 int Nil = 0;
     20 
     21 //构造空的二叉树,因为T是固定数组,不会改变,故不需要&
     22 Status InitBiTree(SqBiTree T){
     23     int i;
     24     for(i=0; i<MAX_TREE_SIZE; i++){
     25         T[i] = Nil; //初始值为空
     26     }
     27     return 1;
     28 }
     29 
     30 //按层序次序输入二叉树的节点的值(字符型或整形),构造顺序存储二叉树
     31 Status CreateBiTree(SqBiTree T){
     32     int i =0;
     33     printf("请按层序输入结点的值(整型),0表示空结点,输999结束。结点数≤%d:
    ",MAX_TREE_SIZE);
     34     while(i<=10){
     35         T[i] = i+1;
     36         if(i!=0&&T[(i+1)/2-1] == Nil&&T[i]!=Nil){
     37             printf("出现了无双亲且非根节点%d
    ",T[i]);
     38             exit(0);
     39         }
     40         i++;
     41     }
     42     //然后将后面的值赋值为空
     43     while(i<MAX_TREE_SIZE){
     44         T[i] = Nil;
     45         i++;
     46     }
     47     return 1;
     48 }
     49 
     50 //清空二叉树,在顺序存储中,两函数完全一样
     51 #define ClearBiTree InitBiTree
     52 
     53 /* 初始条件: 二叉树T存在 */
     54 /* 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */
     55 Status BiTreeEmpty(SqBiTree T){
     56     if(T[0] == Nil){
     57         return 1;
     58     }
     59     return 0;
     60 }
     61 
     62 /* 初始条件: 二叉树T存在。操作结果: 返回T的深度 */
     63 Status BiTreeDepth(SqBiTree T){
     64     //性质2:深度为k的二叉树至多有2^k个节点
     65     int k = 0;
     66     while(powl(2,k)<=(10+1)){
     67         k++;
     68     }
     69     return k;
     70 }
     71 
     72 /* 初始条件: 二叉树T存在 */
     73 /* 操作结果:  当T不空,用e返回T的根,返回OK;否则返回ERROR,e无定义 */
     74 Status Root(SqBiTree T){
     75     TElemType root;
     76     if(BiTreeEmpty(T)){
     77         return 0;
     78     }else{
     79         root = T[0];
     80         return root;
     81     }
     82 }
     83 
     84 /* 初始条件: 二叉树T存在,e是T中某个结点(的位置) */
     85 /* 操作结果: 返回处于位置e(层,本层序号)的结点的值 */
     86 Status Value(SqBiTree T,Position e){
     87     if(e.order <= powl(2,e.level-1)) //不超过每层的节点数
     88         return T[(int)powl(2,e.level-1)+e.order-2];
     89     else
     90         return 0;
     91 }
     92 
     93 /* 初始条件: 二叉树T存在,e是T中某个结点(的位置) */
     94 /* 操作结果: 给处于位置e(层,本层序号)的结点赋新值value */
     95 Status Assign(SqBiTree T,Position e,TElemType value){
     96     int index = (int)powl(2,e.level-1)+e.order-2;
     97     //值不为空,且双亲节点不存在时
     98     if(value!= Nil&&T[(index+1)/2-1]==Nil){
     99         return 0;
    100     }
    101     /*  给双亲赋空值但有叶子 */
    102     else if(value == Nil && (T[index*2+1]!=Nil || T[index*2+2]!=Nil)){
    103         return 0;
    104     }
    105     T[index] = value;
    106     return 1;
    107 }
    108 
    109 //求一个节点的双亲节点
    110 TElemType Parent(SqBiTree T,Position e){
    111     int index = 0;
    112     index = (int)powl(2,e.level-1)+e.order-2;
    113     //为空树或者只有根节点
    114     if(T[0] == Nil ||(T[2*index+1]==Nil || T[2*index+2]==Nil)){
    115         return 0;
    116     }else{
    117         if(index%2==0)
    118             return T[index/2-1];
    119         else
    120             return T[index/2];
    121     }
    122     return 0;
    123 }
    124 
    125 //求一个节点的左孩子节点
    126 TElemType LeftChild(SqBiTree T,Position e){
    127     int index = 0;
    128     index = (int)powl(2,e.level-1)+e.order-2;
    129     if(T[0] == Nil ||(T[2*index+1]==Nil || T[2*index+2]==Nil)){
    130         return 0;
    131     }else{
    132         return T[2*index+1];
    133     }
    134 }
    135 
    136 //求一个节点的右孩子节点
    137 TElemType RightChild(SqBiTree T,Position e){
    138     int index = 0;
    139     index = (int)powl(2,e.level-1)+e.order-2;
    140     if(T[0] == Nil ||(T[2*index+1]==Nil || T[2*index+2]==Nil)){
    141         return 0;
    142     }else{
    143         return T[2*index+2];
    144     }
    145 }
    146 
    147 
    148 //求一个节点的左兄弟节点
    149 TElemType LeftSibling(SqBiTree T,Position e){
    150     int index = 0;
    151     index = (int)powl(2,e.level-1)+e.order-2;
    152     if(T[0] == Nil ||(T[2*index+1]==Nil || T[2*index+2]==Nil)){
    153         return 0;
    154     }else{
    155         if(index%2==0)
    156             return T[index-1];
    157         else 
    158             return 0;
    159     }
    160 }
    161 
    162 //求一个节点的左兄弟节点
    163 TElemType RightSibling(SqBiTree T,Position e){
    164     int index = 0;
    165     index = (int)powl(2,e.level-1)+e.order-2;
    166     if(T[0] == Nil ||(T[2*index+1]==Nil || T[2*index+2]==Nil)){
    167         return 0;
    168     }else{
    169         if(index%2==0){
    170             return 0;
    171         }            
    172         else 
    173             return T[index+1];
    174     }
    175 }
    176 //////////////////////////遍历////////////////////////////
    177 //先序遍历的原则(递归):
    178 void PreTraverse(SqBiTree T,int index){
    179     printf("%d ",T[index]);
    180     if(T[2*index+1]!=Nil){
    181         PreTraverse(T,2*index+1);
    182     }
    183     if(T[2*index+2]!=Nil){
    184         PreTraverse(T,2*index+2);
    185     }
    186 }
    187 void PreOrderTraverse(SqBiTree T){
    188     if(!BiTreeEmpty(T)){
    189         PreTraverse(T,0);
    190     }
    191     printf("
    ");
    192 }
    193 
    194 //中序遍历原则:
    195 void InTraverse(SqBiTree T,int index){
    196 
    197     if(T[2*index+1]!=Nil){
    198         InTraverse(T,2*index+1);
    199     }
    200     printf("%d ",T[index]);
    201     if(T[2*index+2]!=Nil){
    202         InTraverse(T,2*index+2);
    203     }
    204 }
    205 void InOrderTraverse(SqBiTree T){
    206     if(!BiTreeEmpty(T)){
    207         InTraverse(T,0);
    208     }
    209     printf("
    ");
    210 }
    211 
    212 //后序遍历原则:
    213 void PostTraverse(SqBiTree T,int index){
    214 
    215     if(T[2*index+1]!=Nil){
    216         PostTraverse(T,2*index+1);
    217     }
    218     if(T[2*index+2]!=Nil){
    219         PostTraverse(T,2*index+2);
    220     }
    221     printf("%d ",T[index]);
    222 }
    223 void PostOrderTraverse(SqBiTree T){
    224     if(!BiTreeEmpty(T)){
    225         PostTraverse(T,0);
    226     }
    227     printf("
    ");
    228 }
    229 
    230 
    231 
    232 int main(){
    233 
    234     SqBiTree T;
    235     InitBiTree(T);
    236     //创建二叉树
    237     CreateBiTree(T);
    238 
    239     //判断是否为空
    240     printf("二叉树是否为空:%d
    ",BiTreeEmpty(T));
    241 
    242     //清空二叉树后    
    243     //判断是否为空
    244     printf("二叉树是否为空:%d
    ",ClearBiTree(T));
    245     //重新创建二叉树
    246     CreateBiTree(T);
    247 
    248     //树的深度
    249     printf("树的深度:%d
    ",BiTreeDepth(T));
    250 
    251     //树根
    252     printf("树的根节点:%d
    ",Root(T));
    253 
    254     //寻找某一层某个特地的元素
    255     Position e;
    256     e.level = 2;
    257     e.order = 2;
    258     printf("2层第2个是:%d
    ",Value(T,e));
    259 
    260     //修改节点元素
    261     Assign(T,e,50);
    262     printf("2层第2个是:%d
    ",Value(T,e));
    263 
    264     //求节点双亲
    265     printf("2层第2个的双亲是:%d
    ",Parent(T,e));
    266 
    267     //求节点左孩子
    268     printf("2层第2个的左孩子是:%d
    ",LeftChild(T,e));
    269 
    270     //求节点右孩子
    271     printf("2层第2个的左孩子是:%d
    ",RightChild(T,e));
    272     
    273 
    274     //求节点左兄弟
    275     printf("2层第2个的左兄弟是:%d
    ",LeftSibling(T,e));
    276     //求节点右兄弟
    277     printf("2层第2个的右兄弟是:%d
    ",RightSibling(T,e));
    278 
    279 
    280     //先序遍历
    281     printf("先序遍历
    ");
    282     PreOrderTraverse(T);
    283 
    284     //中序遍历
    285     printf("中序遍历
    ");
    286     InOrderTraverse(T);
    287 
    288     //后序遍历
    289     printf("后序遍历
    ");
    290     PostOrderTraverse(T);
    291     return 0;
    292 }

    截图:

     Java代码

     1 package 二叉树的顺序存储结构;
     2 
     3 /**
     4  * 用来定位二叉树中的某一节点
     5  * @author liuzeyu12a
     6  *
     7  */
     8 public class Position {
     9     //层数,序号
    10     int level,order;
    11 }
    View Code
      1 package 二叉树的顺序存储结构;
      2 
      3 public class SqBiTree {
      4 
      5     //初始化二叉树,0代表为空
      6     public void initBiTree(int SqeBiTree[]) {
      7         int i = 0;
      8         while(i<100) {
      9             SqeBiTree[i] = 0;
     10             i++;
     11         }
     12     }
     13     
     14     //创建二叉树
     15     public void createSqeBiTree(int SqeBiTree[]) {
     16         int i = 0;
     17         while(i<=10) {
     18             SqeBiTree[i] = i+1;
     19             i++;
     20         }
     21     }    
     22     //销毁二叉树
     23     public void deleteBiTree(int SqeBiTree[]) {
     24         int i = 0;
     25         while(i<=10) {
     26             SqeBiTree[i] = 0;
     27             i++;
     28         }
     29     }    
     30     
     31     //判断是否为空树
     32     public int emptyBiTree(int SqeBiTree[]) {
     33         if(SqeBiTree[0]==0) 
     34             return 1;
     35         return 0;
     36     }    
     37     
     38     //取根节点
     39     public int rootBiTree(int SqeBiTree[]) {
     40         if(SqeBiTree[0]==0) 
     41             return 0;
     42         return SqeBiTree[0];
     43     }
     44     //取某一层某个特定的元素
     45     public int value(int SqeBiTree[],Position e) {
     46         int index = 0;
     47         index = (int) (Math.pow(2, e.level-1)+e.order-2);
     48         return SqeBiTree[index];
     49     }
     50     //修改取某一层某个特定的元素
     51     public int assign(int SqeBiTree[],Position e,int value) {
     52         int index = 0;
     53         index = (int) (Math.pow(2, e.level-1)+e.order-2);
     54         //值不为空,且双亲节点不存在时
     55         if(value!=0 && SqeBiTree[(index+1)/2-1]==0) {
     56             return 0;
     57         }
     58         //给双亲赋值为空,但是有子叶子
     59         if(value ==0 &&
     60                 (SqeBiTree[2*index+1]!=0 || SqeBiTree[2*index+2]!=0)) {
     61             return 0;
     62         }
     63         SqeBiTree[index] = value;
     64         return 1;
     65     }
     66     /////////////////////////////////开始遍历//////////////////////////////////
     67     //前序遍历
     68     public void preTraverse(int SqeBiTree[],int index) {
     69         System.out.print(SqeBiTree[index]+" ");
     70         if(SqeBiTree[2*index+1]!=0) {
     71             preTraverse(SqeBiTree,2*index+1);
     72         }
     73         if(SqeBiTree[2*index+2]!=0) {
     74             preTraverse(SqeBiTree,2*index+2);
     75         }
     76     }
     77     public void preOrederTraverse(int SqeBiTree[]) {
     78         preTraverse(SqeBiTree,0);
     79         System.out.println("");
     80     }
     81     
     82     //中序遍历
     83         public void inTraverse(int SqeBiTree[],int index) {
     84             if(SqeBiTree[2*index+1]!=0) {
     85                 inTraverse(SqeBiTree,2*index+1);
     86             }
     87             System.out.print(SqeBiTree[index]+" ");
     88             if(SqeBiTree[2*index+2]!=0) {
     89                 inTraverse(SqeBiTree,2*index+2);
     90             }
     91         }
     92         public void inOrederTraverse(int SqeBiTree[]) {
     93             inTraverse(SqeBiTree,0);
     94             System.out.println("");
     95         }
     96     //后序遍历
     97         public void postTraverse(int SqeBiTree[],int index) {
     98             if(SqeBiTree[2*index+1]!=0) {
     99                 postTraverse(SqeBiTree,2*index+1);
    100             }
    101             if(SqeBiTree[2*index+2]!=0) {
    102                 postTraverse(SqeBiTree,2*index+2);
    103             }
    104             System.out.print(SqeBiTree[index]+" ");
    105         }
    106         public void postOrederTraverse(int SqeBiTree[]) {
    107             postTraverse(SqeBiTree,0);
    108             System.out.println("");
    109         }
    110 }
    View Code
     1 package 二叉树的顺序存储结构;
     2 
     3 public class Test {
     4 
     5     public static void main(String[] args) {
     6         int trees[] = new int[100];
     7         SqBiTree tree = new SqBiTree();
     8 
     9         //初始化树
    10         tree.initBiTree(trees);
    11         //创建树
    12         tree.createSqeBiTree(trees);
    13         //判断是否为空树
    14         System.out.println("是否为空树:"+tree.emptyBiTree(trees));
    15         //清空树
    16         tree.deleteBiTree(trees);
    17         System.out.println("是否为空树:"+tree.emptyBiTree(trees));
    18         //重新建树
    19         tree.createSqeBiTree(trees);
    20         //取树根
    21         System.out.println("树根为:"+tree.rootBiTree(trees));
    22         
    23         //取2层2号元素
    24         Position p = new Position();
    25         p.level = 2;
    26         p.order = 2;
    27         //获取2层2号元素的值
    28         System.out.println("2层2号元素的值:"+tree.value(trees, p));
    29         //修改2层2号的值为100
    30         tree.assign(trees, p, 100);
    31         System.out.println("修改后2层2号元素的值:"+tree.value(trees, p));
    32         
    33         
    34         //先序遍历
    35         System.out.print("前序遍历:");
    36         tree.preOrederTraverse(trees);
    37         
    38         //中序遍历
    39         System.out.print("前序遍历:");
    40         tree.inOrederTraverse(trees);
    41         
    42         //后序遍历
    43         System.out.print("前序遍历:");
    44         tree.postOrederTraverse(trees);
    45     }
    46 }
    View Code
  • 相关阅读:
    LRUK算法例子
    php socket编程入门例子
    之前做的一个leetcode的题目记录下(留个纪念)
    php防范时序攻击的办法
    python使用es的例子(记录下)
    mysql随机抽取一定数量的记录
    go module包管理学习笔记
    nginx location匹配规则
    解决go get卡住的问题(转)
    supervisor 学习笔记(转)
  • 原文地址:https://www.cnblogs.com/liuzeyu12a/p/10420665.html
Copyright © 2011-2022 走看看