2014-05-07 11:24:51 +08:00
|
|
|
|
|
|
|
|
#include "stdio.h"
|
2014-05-08 15:01:56 +08:00
|
|
|
#include "stdlib.h"
|
|
|
|
|
#include "time.h"
|
2014-05-07 11:24:51 +08:00
|
|
|
|
|
|
|
|
// 插入排序
|
|
|
|
|
void insert_sort(int *a,int length){
|
|
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
int tmp ;
|
|
|
|
|
int i,j;
|
|
|
|
|
for (i = 1; i < length; ++i)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
for ( tmp=a[i],j=i-1 ; j>=0 && a[j] > tmp ; j--)
|
|
|
|
|
{
|
|
|
|
|
a[j+1]=a[j];
|
|
|
|
|
}
|
|
|
|
|
// j+1是插入的位置
|
|
|
|
|
a[j+1]=tmp;
|
2014-05-07 11:24:51 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
}
|
2014-05-07 11:24:51 +08:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 选择排序
|
|
|
|
|
|
|
|
|
|
void select_sort(int *a,int length){
|
|
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
int min_index,tmp;
|
|
|
|
|
int j;
|
2014-05-07 11:24:51 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
for (int i = 0; i < length; ++i)
|
|
|
|
|
{
|
|
|
|
|
for (j = i+1 ,min_index=i; j < length; ++j)// 不能写成for (int j = i+1 ,min_index=i; j < length; ++j)
|
|
|
|
|
{
|
|
|
|
|
if (a[min_index]>a[j])
|
|
|
|
|
{
|
|
|
|
|
min_index=j;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-05-07 11:24:51 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
//min_index是最小的元素的index
|
|
|
|
|
if (min_index!=i)
|
|
|
|
|
{
|
|
|
|
|
tmp=a[i];
|
|
|
|
|
a[i]=a[min_index];
|
|
|
|
|
a[min_index]=tmp;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2014-05-07 11:24:51 +08:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 冒泡排序
|
|
|
|
|
|
|
|
|
|
void bubble_sort(int *a, int length){
|
|
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
int tmp ;
|
2014-05-07 11:24:51 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
for (int i = 0; i < length-1; ++i) // 第i轮排序
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < length-i; ++j)
|
|
|
|
|
{
|
|
|
|
|
if (a[j] > a[j+1])
|
|
|
|
|
{
|
|
|
|
|
tmp = a[j];
|
|
|
|
|
a[j] = a[j+1];
|
|
|
|
|
a[j+1] = tmp;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-05-07 11:24:51 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
}
|
2014-05-07 11:24:51 +08:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 快速排序
|
|
|
|
|
|
2014-05-08 15:01:56 +08:00
|
|
|
// 挖坑填数,2边向中间扫描
|
|
|
|
|
int partion(int *a, int start,int end){
|
2014-05-07 11:24:51 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
int i=start,j=end;
|
|
|
|
|
int tmp = a[i]; // 这里要做越界检查
|
2014-05-07 11:24:51 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
while(i<j){
|
2014-05-07 11:24:51 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
// 从后向前扫描,找到第一个小于tmp的值,来填a[i]
|
|
|
|
|
while(i<j && a[j]>=tmp){
|
|
|
|
|
j--;
|
|
|
|
|
}
|
|
|
|
|
if (i<j)//找到了,这时候a[j]为坑
|
|
|
|
|
{
|
|
|
|
|
a[i++] = a[j];
|
|
|
|
|
}
|
2014-05-08 15:01:56 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
// 从左向右扫描,找一个大于 tmp的 数, 去填坑a[j]
|
|
|
|
|
while(i<j && a[i]<tmp){
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
if (i<j)
|
|
|
|
|
{
|
|
|
|
|
a[j++]=a[i];
|
|
|
|
|
}
|
2014-05-08 15:01:56 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
}
|
2014-05-08 15:01:56 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
//扫描完成后,i==j
|
|
|
|
|
a[i]=tmp;
|
2014-05-08 15:01:56 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
return i;
|
2014-05-08 15:01:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void quicksort(int *a, int left, int right){
|
|
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
if (left<right)//加上这个,不然有死循环,造成堆栈溢出
|
|
|
|
|
{
|
|
|
|
|
int i = partion(a,left,right);
|
|
|
|
|
quicksort(a,left,i-1);
|
|
|
|
|
quicksort(a,i+1,right);
|
|
|
|
|
}
|
2014-05-07 11:24:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 堆排序
|
|
|
|
|
|
2014-05-09 09:51:52 +08:00
|
|
|
void heap_swop(int *a,int *b){
|
2014-05-08 15:01:56 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
*a = *a + *b;
|
|
|
|
|
*b = *a - *b;
|
|
|
|
|
*a = *a - *b;
|
2014-05-07 11:24:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-05-09 09:51:52 +08:00
|
|
|
//自顶向下调整
|
2019-07-12 09:36:28 +08:00
|
|
|
void heap_public_adjust(int *a,int parent,int length){
|
2014-05-07 11:24:51 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
// 三个数里取最大的一个 a[i],a[2i+1],a[2i+2],跟a[i]交换;然后是 a[(i-1)/2],a[i],a[i+1] .. 一直到a[0]
|
|
|
|
|
int max = parent * 2 + 1;
|
|
|
|
|
while(max < length){
|
|
|
|
|
//三个数里取最大的一个 a[tmp],a[2tmp+1],a[2tmp+2]
|
|
|
|
|
if (max + 1 < length && a[max] < a[max + 1])// left < right
|
2019-07-12 09:36:28 +08:00
|
|
|
{
|
|
|
|
|
max++;
|
2019-07-12 09:51:14 +08:00
|
|
|
}
|
2014-05-09 09:51:52 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
// 和最大孩子比
|
|
|
|
|
if (a[parent] >= a[max])// parent > parent >= max(left, right)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
heap_swop(&a[parent],&a[max]);
|
2019-07-12 09:36:28 +08:00
|
|
|
parent = max; //继续向下, 比对, 交换, 保证所有树 父节点 >= 子节点
|
|
|
|
|
max = 2 * parent + 1;
|
2019-07-12 09:51:14 +08:00
|
|
|
}
|
2014-05-09 09:51:52 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
}
|
2014-05-09 09:51:52 +08:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 从第一个非叶子节点a[(length-2)/2],开始做调整, 跟自己的子节点比较,把最大的孩子换上来就是创建最大堆,
|
|
|
|
|
//反之,把最小的孩子换上来就是创建最小堆 一直到a[0]
|
|
|
|
|
void heap_build(int *a,int length){
|
|
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
|
|
|
|
|
for (int i = (length-2)/2; i >=0 ; --i)
|
|
|
|
|
{
|
|
|
|
|
// 三个数里取最大的一个 a[i],a[2i+1],a[2i+2],跟a[i]交换;然后是 a[(i-1)/2],a[i],a[i+1] .. 一直到a[0]
|
|
|
|
|
heap_public_adjust(a,i,length);
|
|
|
|
|
|
|
|
|
|
}
|
2014-05-09 09:51:52 +08:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 自顶向下调整
|
|
|
|
|
void heap_adjust(int *a,int length){
|
|
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
heap_public_adjust(a,0,length); //对0号调整
|
2014-05-09 09:51:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void heap_sort(int *a, int length){
|
|
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
// 建立堆 大根堆,递增排序
|
|
|
|
|
heap_build(a,length);
|
2014-05-09 09:51:52 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
for (int i = length-1; i >0; --i)
|
|
|
|
|
{
|
|
|
|
|
//交换
|
|
|
|
|
heap_swop(&a[0],&a[i]);
|
|
|
|
|
//调整
|
|
|
|
|
heap_adjust(a,i);
|
|
|
|
|
}
|
2014-05-09 09:51:52 +08:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-15 02:14:18 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// 归并排序
|
|
|
|
|
|
|
|
|
|
// 合并2个有序数组,分配一个临时空间,装a,b的结果,最后,将合并结果拷贝到数组A,是否临时空间
|
|
|
|
|
void merge_array(int *a,int size_a,int *b, int size_b){
|
|
|
|
|
|
|
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
int *tmp = malloc( (size_a+size_b)*sizeof(int) );
|
|
|
|
|
int i,j,k;
|
|
|
|
|
i=j=k=0;
|
2014-05-15 02:14:18 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
while(i<size_a && j<size_b){
|
2014-05-15 02:14:18 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
tmp[k++] = (a[i]>b[j])?b[j++]:a[i++];
|
|
|
|
|
}
|
2014-05-15 02:14:18 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
while(i<size_a){
|
2014-05-15 02:14:18 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
tmp[k++]=a[i++];
|
|
|
|
|
}
|
2014-05-15 02:14:18 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
while(j<size_b){
|
2014-05-15 02:14:18 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
tmp[k++]=b[j++];
|
|
|
|
|
}
|
2014-05-15 02:14:18 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
for (int p = 0; p < k; ++p)
|
|
|
|
|
{
|
|
|
|
|
a[p] = tmp[p];
|
|
|
|
|
}
|
2014-05-15 02:14:18 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
free(tmp);
|
2014-05-15 02:14:18 +08:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void merge_sort(int *a, int length){
|
|
|
|
|
|
|
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
if (length>1)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
merge_sort(a,length/2);
|
|
|
|
|
merge_sort(a+length/2,length-length/2);
|
2014-05-15 02:14:18 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
merge_array(a,length/2,a+length/2,length-length/2);
|
|
|
|
|
}
|
2014-05-15 02:14:18 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-05-09 09:51:52 +08:00
|
|
|
///////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
2014-05-15 02:14:18 +08:00
|
|
|
#define Max_Number 5000
|
2014-05-07 11:24:51 +08:00
|
|
|
|
|
|
|
|
int main(){
|
|
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
//int a[] = {4,87,2,32,5,2,9,49,49,23,45,2,41};
|
|
|
|
|
//准备5000个数
|
|
|
|
|
int a[Max_Number];
|
|
|
|
|
for (int i = 0; i < Max_Number; ++i)
|
|
|
|
|
{
|
|
|
|
|
a[i]=rand()%Max_Number;
|
|
|
|
|
}
|
2014-05-08 15:01:56 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
clock_t start,finish;
|
2014-05-08 15:01:56 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
|
2014-05-08 15:01:56 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
start = clock();
|
|
|
|
|
//merge_sort(a,sizeof(a)/sizeof(int)); // 0.002s,可以看到,归并排序还是很快的
|
|
|
|
|
heap_sort(a,sizeof(a)/sizeof(int)); //
|
|
|
|
|
//quicksort(a,0,sizeof(a)/sizeof(int)-1); // 0.01s
|
|
|
|
|
//insert_sort(a,sizeof(a)/sizeof(int)); // 3.85s
|
|
|
|
|
//select_sort(a,sizeof(a)/sizeof(int)); // 5.3s
|
|
|
|
|
//bubble_sort(a,sizeof(a)/sizeof(int)); // 12.5s
|
|
|
|
|
finish = clock();
|
2014-05-07 11:24:51 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
printf("after sort:\n");
|
|
|
|
|
for (int i = 0; i < sizeof(a)/sizeof(int); ++i)
|
|
|
|
|
{
|
|
|
|
|
printf(" %d ",a[i]);
|
|
|
|
|
}
|
|
|
|
|
printf("time eclipse: %.6f sec\n", (double)(finish-start)/CLOCKS_PER_SEC); // CLOCKS_PER_SEC 1000 clock()是毫秒
|
2014-05-08 15:01:56 +08:00
|
|
|
|
2019-07-12 09:51:14 +08:00
|
|
|
return 0;
|
2014-05-07 11:24:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|