堆排序,插入,删除,调整算法(大顶堆)

#include <stdio.h>  
#include <stdlib.h>  
/*堆以数组为组织方式,下标从0开始*/  
#define INIT_ARRAY_SIZE 50  
/*函数声明部分*/  
void build_heap(int par_array[], int length);  
void max_heap_adjust(int par_array[], int index);  
void heap_sort(int par_array[], int length);  
void max_heap_insert(int **par_array, int item_value);  
void heap_delete(int par_array[], int item_value);  
int left(int index);  
int right(int index);  
/*全局变量*/  
int heap_size;/*堆大小*/  
int heap_cap_size;/*堆容量*/  
/*函数定义部分*/  
/*返回以index为根的完全二叉树的左子树的索引,整个二叉树索引以0为开始*/  
int left(int index)  
{  
    return ((index<<1) + 1);  
}  
/*返回以index为根的完全二叉树的右子树的索引,整个二叉树索引以0为开始*/  
int right(int index)  
{  
    return ((index<<1) + 2);  
}  
/*交换两变量的值*/  
void swap(int * a, int * b)  
{  
    int temp = *a;  
    *a = *b;  
    *b = temp;  
    return ;  
}  
/*  
 * 堆调整 
 * 判断根结点和左右结点的大小,选择最大一个 
 * 如果根大于两个孩子结点,则直接退出; 
 * 否则进行交换,并递归调用调整相应的孩子结点下面的子堆 
 */  
void max_heap_adjust(int par_array[], int index)  
{  
    int left_index;  
    int right_index;  
    int largest = index;  
    left_index = left(index);  
    right_index = right(index);  
    if(left_index <= (heap_size-1) && par_array[left_index] > par_array[largest])  
        largest = left_index;  
    if(right_index <= (heap_size-1) && par_array[right_index] > par_array[largest])  
        largest = right_index;  
    if(index == largest)  
        return ;  
    else  
    {  
        swap(&par_array[index], &par_array[largest]);  
        max_heap_adjust(par_array, largest);  
    }  
}  
/* 
 * 建堆过程 
 * 我们只需依次将以序号为[n/2],  [n/2]-1,…,1的结点作为根的子树都调整为堆即可。 
 */  
void build_heap(int par_array[], int length)  
{  
    heap_size = length;  
    for(int i = ((length-1)>>1); i >= 0; --i)  
    {  
        max_heap_adjust(par_array, i);  
    }  
}  
/* 
 * 堆排序 
 * 首先a[0]和a[n-1]交换,这样在余下的序列a[0-(n-1)]中,只除了根a[0]外,其他各个结点仍然维持堆结构, 
 * 我们再以a[0]开始,做一次堆调整,序列a[0-(n-1)]便调整好了;接下来继续重复上面步骤n-1次,整个序列变得有序. 
 */  
void heap_sort(int par_array[], int length)  
{  
    int i = 0;  
    int temp_heap_size = heap_size;/*保存堆大小*/  
    for(i = length-1; i >= 1; --i)  
    {  
        swap(&par_array[0], &par_array[i]);  
        heap_size--;  
        max_heap_adjust(par_array, 0);  
    }  
    heap_size = temp_heap_size;/*还原堆大小*/  
    return ;  
}  
/* 
 * 堆的插入和删除算法 
 * 堆的插入算法:直接把结点插入到堆末尾,然后从下往上冒泡到合适的位置; 
 * 堆的删除算法:把最后一个结点插入删除结点的位置,然后进行一次调整. 
 */  
void max_heap_insert(int **par_array, int item_value)  
{  
    int index = 0;  
    int father_index = 0;  
    /*如果超过动态数组大小,则对其内容进行扩充*/  
    if(heap_size+1 > heap_cap_size)  
    {  
        *par_array = (int *)realloc(*par_array, 2*INIT_ARRAY_SIZE*sizeof(int));  
    }  
    (*par_array)[heap_size] = item_value;  
    index = item_value;  
    heap_size++;  
      
    while(index)  
    {  
        father_index = (index-1)/2;  
        if((*par_array)[index] > (*par_array)[father_index])  
            swap(&((*par_array)[index]), &((*par_array)[father_index]));  
        index = father_index;  
    }  
}  
void heap_delete(int par_array[], int item_value)  
{  
    int i = 0;  
    for(i = 0; i < heap_size; i++)  
    {  
        if(par_array[i] == item_value)  
            break;  
    }  
    par_array[i] = par_array[heap_size-1];  
    heap_size--;  
    max_heap_adjust(par_array, i);  
}  
int main(void)  
{  
    int i = 0;  
    int del_value = 0;  
    int i_o_array[INIT_ARRAY_SIZE] = {45,68,20,39,88,97,46,59};/*初始数组*/  
    int * i_array = NULL;/*实际存储堆用动态数组*/  
    int array_size/* = sizeof(i_array)/sizeof(int)*/;  
    i_array = (int *)malloc(INIT_ARRAY_SIZE * sizeof(int));  
    array_size = 8;  
    heap_cap_size = INIT_ARRAY_SIZE;  
    /*初始化动态数组*/  
    for(i = 0; i < array_size; ++i)  
        i_array[i] = i_o_array[i];  
    printf("Original array:/n");  
    for(i = 0; i < array_size; ++i)  
        printf("%d/t", i_array[i]);  
    printf("/n");  
    build_heap(i_array, array_size);  
    printf("Heap:/n");  
    for(i = 0; i < array_size; ++i)  
        printf("%d/t", i_array[i]);  
    printf("/n");  
    heap_sort(i_array, array_size);  
    printf("After heap sort:/n");  
    for(i = 0; i < array_size; ++i)  
        printf("%d/t", i_array[i]);  
    printf("/n");  
    del_value = 45;  
    heap_delete(i_array, del_value);  
    array_size--;  
    build_heap(i_array, array_size);  
    printf("Delete %d:/n", del_value);  
    for(i = 0; i < array_size; ++i)  
        printf("%d/t", i_array[i]);  
    printf("/n");  
    build_heap(i_array, array_size);  
    max_heap_insert((int **)&i_array, 45);  
    array_size++;  
    printf("Insert %d:/n", del_value);  
    for(i = 0; i < array_size; ++i)  
        printf("%d/t", i_array[i]);  
    printf("/n");  
    heap_sort(i_array, array_size);  
    printf("After heap sort:/n");  
    for(i = 0; i < array_size; ++i)  
        printf("%d/t", i_array[i]);  
    printf("/n");  
    system("pause");  
    return 0;  
}  
/* 
结果输出: 
Original array: 
45      68      20      39      88      97      46      59 
Heap: 
97      88      46      59      68      20      45      39 
After heap sort: 
20      39      45      46      59      68      88      97 
Delete 45: 
97      59      88      46      39      68      20 
Insert 45: 
97      59      88      46      39      68      20      45 
After heap sort: 
20      39      45      46      59      68      88      97 
请按任意键继续. . . 
*/  

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值