Files
Learn-Algorithms/Sort/insert_sort.c
T

296 lines
5.7 KiB
C
Raw Normal View History

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
}