1.插入排序:
void InsertSort(int * s,int n){
int i=0;
for(i=0;i<n-1;i++){
int temp=s[i+1]; //注意要将a[j+1]记录下来,因为swap会改变a[j+1]的值
for(int j=i;j>=0;j--){
if(s[j]>temp){
Swap( &s[j],&s[j+1]);
}
else break;
}
}
}
[1]原理
以{5,2,4,6,1,3}为例,
两个for循环嵌套,循环遍历查找需要插入的数字.每次swap(标红为temp的值):
5 | 2 | 4 | 6 | 1 | 3 |
2 | 5 | 4 | 6 | 1 | 3 |
2 | 4 | 5 | 6 | 1 | 3 |
2 | 4 | 5 | 6 | 1 | 3 |
2 | 4 | 5 | 1 | 6 | 3 |
2 | 4 | 1 | 5 | 6 | 3 |
2 | 1 | 4 | 5 | 6 | 3 |
1 | 2 | 4 | 5 | 6 | 3 |
1 | 2 | 4 | 5 | 6 | 3 |
. . . . . . (同理)
1 | 2 | 3 | 4 | 5 | 6 |
[2]时间复杂度
Best(即输入数组已经是排好序的了):
O(n)
Worst(输入数组为倒序排列):
[3]优化方案(希尔排序)*
void shellsort(data* a,int n) {
int i = 0, j = 0;
int gap;//gap为1就是直接插入排序
gap = n;
while (gap > 1) {
gap = gap / 2;//gap的取值一定要保证最后一次为1
//gap=gap/3+1
//gap大于1是为预排序
data temp = 0;
for (j = 0; j < n - gap; j++) {//保证每组都能够预排
temp = a[j + gap];
for (i = j; i >= 0; i -= gap) {
if (a[i] > temp) {
swap(&a[i], &a[i + gap]);
}
else break;
}
}
}
}
2.归并排序(递归)
void MergeSort(int * s,int left,int right,int *tmp){
if(left>=right)return ;
int mid=(left+right)/2;
MergeSort(s,left,mid,tmp);
MergeSort(s,mid+1,right,tmp);
int begin1=left,begin2=mid+1,end1=mid,end2=right;
int i=left;
while(begin1<=end1&&begin2<=end2){//归并
if(s[begin1]<=s[begin2]){
tmp[i++]=s[begin1];
begin1++;
}
else if(s[begin2]<s[begin1]){
tmp[i++]=s[begin2];
begin2++;
}
}
while(begin2<=end2){
tmp[i++]=s[begin2];
begin2++;
}
while(begin1<=end1){
tmp[i++]=s[begin1];
begin1++;
}
for(i=left;i<=right;i++){
s[i]=tmp[i];
}
}
void Merge(int *s,int n){//递归方法
int * tmp=(int *)malloc(sizeof(int )*n);
MergeSort(s,0,n-1,tmp);
free(tmp);
}
[1]原理
二路归并如图
[2]时间复杂度
logn即将数组n个元素分为单独数需要的步数,在归并过程中,需要对n个数一次遍历比较排序即n步,相乘即。
[3]非递归算法*
void MergeSortNonR(data* a, int n) {//归并排序的非递归方法
data* tmp = (data*)malloc(sizeof(int) * n);
int gap=1;//每组数据的个数
while (gap < n) {
for (int i = 0; i < n; i += 2 * gap) {
//[i,i+gap-1][i+gap,i+2gap-1]
int begin1 = i, end1 = i + gap - 1;
int begin2 = i + gap, end2 = i + 2 * gap - 1;
//可能最后的右半区间不存在
if (begin2 >= n) {
break;
}
//右半区间多了,修正一下end2的位置
if (end2 >= n) {
end2 = n - 1;
}
int index = i;//起始的位置不一定为零
//归并
while (begin1 <= end1 && begin2 <= end2) {
if (a[begin1] < a[begin2]) {
tmp[index++] = a[begin1];
begin1++;
}
else if (a[begin2] <= a[begin1]) {
tmp[index++] = a[begin2];
begin2++;
}
}
while (begin1 <= end1) {
tmp[index++] = a[begin1++];
}
while (begin2 <= end2) {
tmp[index++] = a[begin2++];
}
for (int j = i; j <=end2; j++) {//拷贝回a
a[j] = tmp[j];
}
}
printf("\n");
gap *= 2;
}
}
3.冒泡排序
void BubbleSort(int *s,int n){
int i=0,j=0;
for(i=0;i<n;i++){
for(j=0;j<n-i-1;j++){
if(s[j]>s[j+1])Swap(&s[j],&s[j+1]);
}
}
}
[1]原理
可视化:
[2]时间复杂度
[3]优化算法*
void BubbleSort(int *s,int n){
int i=0,j=0;
int flag=1;
for(i=0;i<n&&flag==1;i++){
flag=0;
for(j=0;j<n-i-1;j++){
if(s[j]>s[j+1]){
Swap(&s[j],&s[j+1]);
flag=1;
}
}
}
}
4.时间复杂度比较#1
利用Timer()函数得到数量级为10^5的随机数组以及运行时间:
#include <mm_malloc.h> #include <time.h> long long int ARRAY_SIZE=100000;
int array[ARRAY_SIZE]; int i; srand(time(NULL)); for (i = 0; i < ARRAY_SIZE; i++) { array[i] = rand(); } clock_t start, end; double milliseconds; start = clock(); InsertSort(array,ARRAY_SIZE); end = clock(); //其他算法...
得到结果如下:
(PS:优化后的冒泡排序为22403.00 ms,变化不大(doge))