二叉树主要有两种实现方式,数组形式和链表形式,其中数组形式是利用完全二叉树的性质5:
性质5:如果对一棵有n个结点的完全二叉树的结点按层序编号,则对任一结点i(1in),有: (1) 如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是i/2 (2) 如果2i>n,则结点i无左孩子;如果2in,则其左孩子是2i (3) 如果2i+1>n,则结点i无右孩子;如果2i+1n,则其右孩子是2i+1
来实现的,左边的节点的下标是根节点的下标的2倍,右边的节点的下标是根节点下标的2倍加1。千万要记住这个只能用于完全二叉树(满二叉树其实就是更加完美的完全二叉树),上篇文章写的那种多杈树是用不了的,一般的二叉树也只是有的能用。。(估计很少,就当做不能用吧)。
对应树的操作我用数组实现了树的插入,删除,遍历。因为二叉树是一个完全二叉树,插入以后也要维持完全二叉树的性质,所以看来只能在数组的最后一位插入了。删除的我写了一个从中间节点删的函数,但是感觉实用价值不是很大。
这里是实现代码:
#include<stdio.h> char src[10]={0,'a','b','c','d','e','f'};//6个元素 int length(char a[]){ int ret = 1; while(a[ret]!=0){ret++;} return ret; } void insert(char data){ int srclen = length(src); src[srclen] = data; } void del(int index){ //把数组index后面的内容都往前面挪一位 int cur_l = length(src) - 1; src[index] = 0; for(int i=index;i<cur_l;i++){ src[i] = src[i+1]; } src[cur_l] = 0; } void preorder(int n){ if(n>length(src)){return;} printf("%c",src[n]); preorder(2*n); preorder(2*n+1); } void print(){ int srclength = sizeof(src)/sizeof(char); for(int i=0;i<srclength;i++){ printf("%c",src[i]); } printf("\n"); } int main(){ print(); insert('h'); print(); del(2); print(); preorder(1);//从1开始 return 0; }
sizeof(src)/sizeof(char)这个东西它始终等于的是数组开辟的个数,这里也就是一直等于10.所以不能用它来控制循环的。。。坑