直接排序是我常见的一种排序方法,是一种稳定的排序,时间复杂度平均为O(n),
我们平常生活中也经常无意的用到,比如说打牌的时候经常要排序。
首先想想我们打牌的时候是怎么整理我们的牌的,一开始的时候有可能是完全无序的也有可能是一部分有序的,但是我们就把无序的牌直接插到有序的牌中,并且把比插入的牌大的牌往后移。
把问题抽象成程序中的话,意思为有着n个元素的数组a[n],其中前面k项为有序的,后面的n-k项是无序的,我们要做的是把后面的n-k项插入到前面的k项中,形成一个大的有序数组。
举个栗子:
int a[3]={2,5,3};
这个数组我们要把它排序,我们来模拟一边这个直接插入排序的详细过程。
外循环
第一步,从第一个开始,因为我们是用后面的跟前面的比较,因为a[0]=2,第零个的前面的没有数据了。
当前的我们观察的是a[1]=5,把5存起来,明显比a[0]大,所以不做任何操作。
第二步,我们观察的是a[2]=3,把3存起来,跟前面的a[1]=5比较,比a[2]=3大
内循环
往前比较,现在比较的是a[1]=5,跟存好的3比较,比3大,往后移a[2]=a[1]
现在的数组是{2,5,5};
继续往前,a[0]=2,跟存好的3比较,比3小,找到插入的位置,把存好的3放入a[0]之后。
得出数组为{2,3,5};
为什么要两个循环呢?因为遍历的时候,除了往后移动当前的第一个无序的,还要跟之前排好序的进行遍历比较找到适合的插入的位置。
现在贴上代码:
void Mysort(int arr[],int n)
{
for(int i=1;i<n;i++)
{
int temp=arr[i];
int j=i-1;
while(j>=0&&arr[j]>temp)
{
arr[j+1]=arr[j]; //遍历前面排好序的元素,并且进行移动
j--;
}
arr[j+1]=temp; //插入到合适的位置
}
}
下面插入完整的代码:
#include "stdafx.h"
#include <time.h>
#include <stdlib.h>
#define NUMSIZE 20000
void Mysort(int arr[],int n)
{
for(int i=1;i<n;i++)
{
int temp=arr[i];
int j=i-1;
while(j>=0&&arr[j]>temp)
{
arr[j+1]=arr[j]; //把大的数据往后移动
j--;
}
arr[j+1]=temp; //插入到合适的位置
}
}
int main(int argc, char* argv[])
{
float nstart=clock();
srand((unsigned)time(NULL));
//产生2万个随机数
int a[NUMSIZE];
for (int i=0; i<NUMSIZE; i++)
a[i]=rand()%NUMSIZE; //产生0-20000
Mysort(a,NUMSIZE);
for( i=0;i<NUMSIZE;i++)
printf("%d\n",a[i]);
float nend=clock();
printf("运行时间:%f\n",(nend-nstart)/1000);
return 0;
}
下面是10和元素的运行时间:
下面是20000个数据的排序情况