4、堆排序法
堆的定义:堆是一个完全二叉树,树中每个结点对应于原始数据的一个记录,并且每个结点应满足以下条件:非叶结点的数据大于或等于其左、右孩子结点的数据(若是按从大到小的顺序排序,则要求非叶结点的数据小于或等于其左、右孩子结点的数据)。
步骤:1、构成堆
(1)将无序数据放入完全二叉树的各结点。
(2)由二叉树的下层向上层逐层对父子结点的数据进行比较,使用一种称为“筛”的运算进行结点数据的调整,直到使结点最后满足堆的条件为止。
2、利用堆排序
(1)取堆的根结点(最大值),将其放到数组的最后。
(2)重新执行构成堆的方法,对堆进行重新构成。此时,应将最后一个结点排除在外。
(3)重复上述过程,逐步从根结点取出最大值,放入到数组的后面,再对剩下的结点重新构成堆,直到只剩下一个结点,即可得到有序的数据。
源码:
#include <stdio.h>
#include <stdlib.h>
#define ARRAYLEN 10
void HeapAdjust(int a[], int s, int n) //构成堆
{
int j,t;
while(2*s+1 < n) //第s个结点有右子树
{
j = 2*s+1;
if((j+1) < n)
{
if(a[j] < a[j+1]) //左子树小于右子树,则需要比较右子树
j++; //序号增加1,指向右子树
}
if(a[s] < a[j]) //比较s与j为序号的数据
{
t = a[s]; //交换数据
a[s] = a[j];
a[j] = t;
s = j; //堆被破坏,需要重新调整
}
else //不再需要调整
break; //退出循环
}
}
void HeapSort(int a[], int n) //堆排序
{
int t,i,j;
for(i = n/2 - 1; i >= 0; i--) //将a[0]至a[n-1]构成堆
HeapAdjust(a,i,n);
for(i = n - 1; i > 0; i--) //取根结点与末结点交换
{
t = a[0]; //与第i个记录交换
a[0] = a[i];
a[i] = t;
HeapAdjust(a,0,i); //将a[0]至a[i]重新调整
}
}
int main()
{
int i,a[ARRAYLEN] = {23,32,14,76,2,98,65,34,23,10}; //定义数组
HeapSort(a,ARRAYLEN);
printf("排序后:");
for(i = 0; i < ARRAYLEN; i++) //输出排序后的结果
printf("%d ",a[i]);
printf("\n");
system("pause");
return 0;
}
5、直接插入排序
算法描述:
(1)对于第一个元素,因为没有比较,将其作为已经有序的序列。
(2)从数组中获取下一个元素,在已经排序的元素序列中从后向前扫描,并进行判断。
(3)若排序序列的元素大于新元素,则将该元素移到下一位置
(4)重复步骤(3),直到找到已排序的元素小于或者等于新元素的位置
(5)将新元素插入到该位置
(6)重复步骤(2)~步骤(5),直到将数组中的数据处理完
源码:
#include <stdio.h>
#include <stdlib.h>
#define ARRAYLEN 10
void InsertSort(int a[], int n) //直接插入排序
{
int i,j,t;
for(i = 1; i < n; i++)
{
t = a[i]; //取出一个未排序的数据
for(j=i - 1; j >= 0 && t<a[j];j--) //在排序序列中查找位置
a[j+1] = a[j]; //向后移动数据
a[j+1] = t; //插入数据到序列
}
}
int main()
{
int i,a[ARRAYLEN] = {23,32,14,76,2,98,65,34,23,10}; //定义数组
InsertSort(a,ARRAYLEN); //调用插入排序函数
printf("排序后:");
for(i = 0; i < ARRAYLEN; i++)
printf("%d ",a[i]);
system("pause");
return 0;
}