二叉树的数组存储及运算

二叉树的数组存储

当用数组存储完全二叉树时可以用节点的编号作为数组下标
当用数组存储非完全二叉树时也可以用节点的编号作为数组下标,但是要补全节点序列.(用虚拟节点)


2017/8/30 更新
父子节点的位置运算:
数组0下标不使用
父节点i的左子节点在位置(2*i);
父节点i的右子节点在位置(2*i+1);
子节点i的父节点在位置(i/2);

完整代码如下:

//this is tree node size
#define SIZE 20

//求深度
//完全二叉树的最大节点数量s = (2^n)-1,n = 树的高度
//对于一个数组结构的tree,要先求tree的深度n,求最大指数2^n-1=size = 2^n = size+1 。所以 n =  log2 (size+1)。n向上取整
int getHeight2(int size){
    return (int)ceil(log10((double)size+1)/log10(2.0));
}

//求左孩子
int *getLchild(int arr[],int index){
    if(index*2 > SIZE){
        //printf("this node is not lift child");
        return NULL;
    }
    return &arr[index*2];
}

//求右孩子
int *getRchild(int arr[],int index){
    if(index*2+1 > SIZE){
    //  printf("this node is not right child");
        return NULL;
    }
    return &arr[index*2+1];
}

//求双亲
int *getParent(int arr[],int index){
    if(index < 2 || index > SIZE){
        printf("this node is not parent");
        return NULL;
    }
    return &arr[index/2];
}

//先序遍历
void perorder2(int *arr, int len){

    printf("%d  ",arr[len]);
    if(getLchild(arr,len) != NULL)
    perorder2(arr,*getLchild(arr,len));

    if(getRchild(arr,len) != NULL)
    perorder2(arr,*getRchild(arr,len));
}

//打印空格
void printCH(int k){
    char *ch = " ";

        while(k){
            printf("%s",ch);
            k--;
        }
}

//print tree
//打印tree,这样有直观的感受,按层打印
void printTerr(int arr[]){

    int tall = getHeight2(SIZE);//树的高度,层数

    int count = 0,length = 1, i;//换行计数

    int k;//元素间距




    //k 的值用于控制tree node 间距,当从root节点向下打印时, k是递减的,k的递减规律是: n = (n+1) - 2^n ;(n 是当前层数,n-1表示上一层,root的层数n = 数的高度,n从叶子(最末端)向根节点计数.2^n == 1<<n)
    k = (1 << (tall+1)) - 1;
    k = k - (1 << tall);


    for(i = 1; i <= SIZE; i++){

        printCH(k);//打印空格方法
        printf("%d",arr[i]);//打印元素,每个元素前后要打印空格.
        printCH(k);

        count++;

        //判断是否打印空格,调整层数
        if(count == length){
            printf("\n\n");

            count = 0;
            length *=2;

            tall--;
            k = k - (1 << tall);
        }
    }
    printf("\n");
}


//test tree for array
void treeArrsTest(){
    int treeArr[] = {NULL,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

    //先把tree打印出来,这样比较直观一点
    printTerr(treeArr);
    printf("\n");
    perorder2(treeArr, 1);
    printf("\n");

    printf(" node 5 left child is  : %d\n",*getLchild(treeArr,5));
    printf(" node 5 right child is 6 : %d\n",*getRchild(treeArr,5));
    printf(" node 5 parent is : %d\n",*getParent(treeArr,5));
}

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值