各种排序算法,时间复杂度On及比较#1

 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的值): 

524613
254613
245613
245613
245163
241563
214563
124563
124563

                                                                      . . . . . . (同理)

123456

[2]时间复杂度

                    Best(即输入数组已经是排好序的了): 

                                                                        O(n)

                    Worst(输入数组为倒序排列):

                                                                        T\left ( n \right )\approx \left (\sum_{1}^{n}i \right )\approx O(n^{2})

[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]时间复杂度

                                                       O\left ( n\cdot logn \right )

        logn即将数组n个元素分为单独数需要的步数,在归并过程中,需要对n个数一次遍历比较排序即n步,相乘即O\left ( n\cdot logn \right )

[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]时间复杂度

                                                            O\left ( n^{2} \right )

[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))

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值