堆排序
堆
要想了解堆排序首先我们要了解堆。
堆:堆一般指的是二叉堆,顾名思义,二叉堆是完全二叉树或者近似完全二叉树
堆的性质
① 是一棵完全二叉树
② 每个节点的值都大于或等于其子节点的值,为最大堆;反之为最小堆
:该完全二叉树的子结点都大于父结点所以为最小堆
堆的储存
用数组来表示堆,下标为i结点的父结点下标为(i-1)/2;而其左右子结点分别为(2i+1),(2i+2)
所以上图所示的堆可以用a[11] = {0,1,2,3,4,5,6,7,8}来表示
堆排序的定义
堆排序是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父结点。
基本思想
1.将待排序的数列构造成一个最大堆,这时数列的最大值为根结点。
2.将根结点与待排序列的最后一个元素交换
3.再将其剔除并将其他的元素维护成一个最大堆,最终排序出来的是为一个递增序列
实现步骤.
sort.h
#ifndef _SORT_H_
#define _SORT_H_
void produce_arr(int *__src, int length);
void traversal_arr(int *__src, int length);
void swap(int *__src, int *__dest);
void heapadjust(int *__src, int length, int i);
void heapsort(int *__src, int length);
#endif
sort.c
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include"sort.h"
void produce_arr(int *__src, int length)
{
srand(time(NULL));
for(int i = 0;i<length;i++)
__src[i] = rand()%100;
}
void traversal_arr(int *__src, int length)
{
for (int i = 0; i < length; i++)
{
printf("%d ",__src[i]);
}
printf("\n");
}
void swap(int *__src, int *__dest)
{
int temp = *__src;
*__src = *__dest;
*__dest = temp;
}
//堆排序;
void heapadjust(int *__src, int length, int i)
{
int max = i;
int lchild = i*2+1;
int rchild = i*2+2;
if(lchild < length && __src[max] < __src[lchild])
max = lchild;
if (rchild < length && __src[max] < __src[rchild])
max = rchild;
if(max != i)
{
swap(&__src[max],&__src[i]);
heapadjust(__src,length,max);
}
}
void heapsort(int *__src, int length)
{
int i;
for(i=length/2-1;i>=0;i--)
heapadjust(__src,length,i);
for(i=length-1;i>0;i--)
{
swap(&__src[i],&__src[0]);
heapadjust(__src,i,0);
}
}
主函数
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include"sort.h"
#define LENGTH 10
int main()
{
int arr[LENGTH];
produce_arr(arr, LENGTH);
printf("the original array is:\n");
traversal_arr(arr, LENGTH);
heapsort(arr, LENGTH);
printf("after the heapsort is:\n");
traversal_arr(arr, LENGTH);
return 0;
}