C和指针 第十七章 习题

17.8 为数组形式的树编写模块,用于从树中删除一个值,如果没有找到,程序节点

 ArrayBinaryTree.c

//
// Created by mao on 16-9-18.
//

#include "ArrayBinaryTree.h"
#include <assert.h>
#include <stdio.h>

unsigned long leftChild(unsigned long current)
{
    return 2 * current;
}

unsigned long rightChild(unsigned long current)
{
    return  2 * current + 1;
}

void insert(TREE_TYPE value)
{
    int current = 1;
    while(tree[current] != 0 && current < TREE_SIZE){
        if(tree[current] < value){
            current = 2 * current + 1;
        }else if(tree[current] > value){
            current = 2 * current;
        }else {
            //一插入直接返回
            return ;
        }
    }
    assert(current <= TREE_SIZE);
    tree[current] = value;
}

TREE_TYPE *find(TREE_TYPE value)
{
    int current = 1;
    while(tree[current] != 0 && current < TREE_SIZE){
        if(tree[current] < value){
            current = 2 * current + 1;
        }else if(tree[current] > value){
            current = 2 * current;
        }else {
            //找到值
            break;
        }
    }
    assert(current <= TREE_SIZE);
    return (tree + current);
}

//先序遍历
void do_pre_order_traverse(unsigned long current)
{
    if(tree[current] != 0){
        printf("%d ", tree[current]);
        do_pre_order_traverse(leftChild(current));
        do_pre_order_traverse(rightChild(current));
    }
}

//寻找current树下面的最大值的树,返回指向该地址的指针
TREE_TYPE *findMax(unsigned long current)
{
    assert(tree[current] != 0);
    while(tree[current] != 0){
        current = rightChild(current);
    }
    return tree + (current / 2);
}
//寻找最小树
TREE_TYPE *findMin(unsigned long current)
{
    assert(tree[current] != 0);
    while(tree[current] != 0){
        current = leftChild(current);
    }
    return tree + (current / 2);
}

//查找左子树最大节点然后替换,然后删除最大节点
void delete(TREE_TYPE value)
{
    TREE_TYPE *ptr = find(value);
    TREE_TYPE temp;
    //待删除节点的下标
    unsigned long current = ptr - tree;

    if(tree[leftChild(current)] != 0 && tree[rightChild(current)] != 0){
        //如果有两个子树,用左子树最大值替换,然后删除最大值树
        TREE_TYPE *leftMax = findMax(leftChild(current));
        temp = *leftMax;
        //删除最大值然后替换
        delete(temp);
        tree[current] = temp;
    }else if(tree[leftChild(current)] == 0 && tree[rightChild(current)] == 0){
        //如果没有子树
        tree[current] = 0;
    }else{
        if(tree[leftChild(current)] != 0){
            //左子树,最大值树删除,替换
            TREE_TYPE *leftMax = findMax(leftChild(current));
            //删除最大值然后替换
            delete(*leftMax);
            tree[current] = *leftMax;
        }else{
            //只有右子树,右子树最小值替换
            TREE_TYPE *rightMin = findMin(rightChild(current));
            temp = *rightMin;
            delete((temp));
            tree[current] = temp;
        }
    }
}

ArrayBinaryTree.h

//
// Created by mao on 16-9-18.
//

#ifndef ARRAYBINARYTREE_H
#define ARRAYBINARYTREE_H
#define TREE_SIZE 100
#define ARRAY_SIZE (TREE_SIZE + 1)
typedef int TREE_TYPE;
static TREE_TYPE tree[ARRAY_SIZE] = {0};

unsigned long leftChild(unsigned long current);
unsigned long rightChild(unsigned long current);
void insert(TREE_TYPE value);
TREE_TYPE *find(TREE_TYPE value);
void delete(TREE_TYPE value);
void do_pre_order_traverse(unsigned long current);
TREE_TYPE *findMax(unsigned long current);
TREE_TYPE *findMin(unsigned long current);
#endif //ARRAYBINARYTREE_H

main.c

#include <stdio.h>
#include "ArrayBinaryTree.h"

int main()
{
    insert(20);
    insert(12);
    insert(5);
    insert(9);
    insert(16);
    insert(17);
    insert(25);
    insert(28);
    insert(26);
    insert(29);
    do_pre_order_traverse(1);
    delete(25);
    delete(20);

    printf("\n");
    do_pre_order_traverse(1);
    return 1;
}

运行:

 

转载于:https://www.cnblogs.com/yangxunwu1992/p/5881108.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值