#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
请按任意键继续. . .
*/
堆排序,插入,删除,调整算法(大顶堆)
最新推荐文章于 2022-11-28 21:19:50 发布