前言:
前面有点事耽误了一阵子,本来想写完数据结构再复习Java的...还是先补完把。
话不多说,前面我们已经学习到了数据的链式存储结构,相对于下面要讲的顺序存储结构难些。因为树是一种一对多的数据结构,由于它的特殊性
使用顺序存储结构也可以实现。
顺序存储二叉树:
二叉树的顺序存储结构就是一维数组存储二叉树中的节点,并且节点的存储位置,也就是数组下标要能体现节点之间的关系,比如双亲和孩纸的关系。左右兄弟关系等。
来看看一颗完全二叉树的顺序存储:
将这两颗树存储到数组里面,注意下标的表示位置
这下子可以看出完全二叉树的优越性来了把。然而也有出现一些极端的情况,如
这种普通的二叉树显然是对存储空间的浪费,所以遇到这种情况的二叉树,建议使用链式二叉树,我们的顺序存储二叉树适合使用在完全二叉树下
C代码
1 #include2 #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 ){ 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:\n",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\n",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("\n"); 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("\n"); 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("\n"); 228 } 229 230 231 232 int main(){ 233 234 SqBiTree T; 235 InitBiTree(T); 236 //创建二叉树 237 CreateBiTree(T); 238 239 //判断是否为空 240 printf("二叉树是否为空:%d\n",BiTreeEmpty(T)); 241 242 //清空二叉树后 243 //判断是否为空 244 printf("二叉树是否为空:%d\n",ClearBiTree(T)); 245 //重新创建二叉树 246 CreateBiTree(T); 247 248 //树的深度 249 printf("树的深度:%d\n",BiTreeDepth(T)); 250 251 //树根 252 printf("树的根节点:%d\n",Root(T)); 253 254 //寻找某一层某个特地的元素 255 Position e; 256 e.level = 2; 257 e.order = 2; 258 printf("2层第2个是:%d\n",Value(T,e)); 259 260 //修改节点元素 261 Assign(T,e,50); 262 printf("2层第2个是:%d\n",Value(T,e)); 263 264 //求节点双亲 265 printf("2层第2个的双亲是:%d\n",Parent(T,e)); 266 267 //求节点左孩子 268 printf("2层第2个的左孩子是:%d\n",LeftChild(T,e)); 269 270 //求节点右孩子 271 printf("2层第2个的左孩子是:%d\n",RightChild(T,e)); 272 273 274 //求节点左兄弟 275 printf("2层第2个的左兄弟是:%d\n",LeftSibling(T,e)); 276 //求节点右兄弟 277 printf("2层第2个的右兄弟是:%d\n",RightSibling(T,e)); 278 279 280 //先序遍历 281 printf("先序遍历\n"); 282 PreOrderTraverse(T); 283 284 //中序遍历 285 printf("中序遍历\n"); 286 InOrderTraverse(T); 287 288 //后序遍历 289 printf("后序遍历\n"); 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 }
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 }
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 }