常见排序算法

1.冒泡排序(Bubblesort)

思想:冒泡排序,是通过将一组数两两比较,每一趟会将最大或最小的数沉到最底,每一趟比较完后下一趟就会少比较一次,最后一趟完成后这组数据就会变为一组有序的数。

时间复杂度

当一组数为有序且期望排序顺序同序时,比较次数与移动次数都达到最小值c(比较次数)=n-1,m(移动次数)= 0;

时间复杂度最小为o(n);

当一组数有序但期望排序与顺序相反时,比较次数与移动次数都达到最大值c = (n-1)+(n-2)+......+1 = n(n-1)/2 = o(n^2),m = 3n(n-1)/2 = o(n^2);

时间复杂度最大为o(n^2);

代码:

void Bubblesort(int arry[MAX_SIZE])
{
	int t;
	int *p = arry;
	int *q = arry;
	for(;p < &arry[MAX_SIZE-1];p++)
	{
		int i = 0;
		for(q =arry;q < &arry[MAX_SIZE-i-1];q++)
		{
			if(*q > *(q+1))
			{
				t = *q;
				*q = *(q+1);
				*(q+1) = t;
			}
		}
		i++;
	}
}
2.选择排序(selection sort)
思想: 将一组数的第一个位置作为最小/最大数的位置(假设的),遍历整组数,找到目前最小/最大的与当前最小/最大位置(假设的)交换位置,遍历一次完成后,向后移动最小/最大数的位置(假设的),再次遍历,直到整组数有序。
时间复杂度:

第一个位置设为最小/最大位置时,若该位置数为最小/最大,且这组数为升序/降序,此时时间复杂度最小

时间复杂度最小为o(n);

第一个位置设为最小/最大位置时,若该位置数为最大/最小,且这组数为降序/升序,此时时间复杂度最大

时间复杂度最大为o(n^2);

代码:

void selectionsort(int *arry)
{
	for(int i = 0 ;i < MAX_SIZE;++i)
	{
		int min = i;
		for(int j = i;j < MAX_SIZE;++j)
		{
			if(arry[j] < arry[min])
			{
				min = j;
			}
		}
		if(min != i)
		{
			int t = arry[min];
			arry[min] = arry[i];
			arry[i] = t;
		}
	}
}
3.插入排序(insertionsort)

思想:将一组数分为两种,有序与无序,开始时将第一个元素看为有序部分,然后将后面紧连着的无序部分的第一个数与前面有序部分比较,插入到有序部分,并且保持有序部分的有序。然后用与前面一样的方法将无序部分的元素挨个插入到有序部分,最后使整组数完全有序。

时间复杂度:

当一开始整组数为有序,且升序或降序的期望与顺序相同时,时间复杂度最小;

时间复杂度最小为o(n);

当整组数有序时,但升序或降序的期望与顺序相反时,时间复杂度最高;

时间复杂度最高为o(n^2);

void insertionsort(int *arry)
{
	int i = 1, j = 0;
	int t = 0;
	for(i;i < MAX_SIZE;++i)
	{
		t = arry[i]; //将要插入的数放入临时容器t中
		j = i-1;     //j为有序部分的最后一个元素的下标
		while(j >= 0 && t < arry[j])//找到将要插入的数的位置
		{
			arry[j+1] = arry[j];//将有序元素往后移
			j--;
		}
		arry[j+1] = t;//将要插入的元素插入
	}
}
4.希尔排序(shellsort)

思想:希尔排序主要用了分治的思想,引入步长的概念提高插入排序的效率,对于一组数,规定步长将符合步长的多个数用插入排序进行排序,再重新组合起来,然后缩短步长再次排序,当步长为1时整组数的无序性很低,再次插入排序后就得到了有序的一组数。

时间复杂度:

希尔排序的时间复杂度与步长的选取有关,步长与时间复杂度对应关系如下:

希尔增量(n/2)                                         时间复杂度:o(n^2)

hibbard增量{2*k-1,......,7,3,1}                  时间复杂度:0(n^(3/2))

                                                              最小的时间复杂度:o(n*log2n)

代码:

void shellsort(int v[])//希尔增量
{
    int gap,i,j,temp;
    for (gap = MAX_SIZE/2; gap > 0; gap /= 2)
    {
        for(i = gap; i < MAX_SIZE; i++)

            for(j = i-gap; j>=0 && v[j]>v[j+gap]; j -= gap)
            {
                temp = v[j];
                v[j] = v[j+gap];
                v[j+gap] = temp;
            }           
    }
}
5.快速排序(quicksort)

思想:开始时随意找数组中的某个数作为"基准数",然后按照(从右往左)再(从左往右)的顺序依次寻找比基准数(小)和比基准数(大)的,数,如果没有相遇,就将两个数相互交换,直到两个数相遇,再将此时的数与基准数交换位置,这时基准数左边的数都是比基准数小的,右边都是比基准数大的。然后对基准数左右分别进行快排,如此循环,最后整组数就排序完成了。

时间复杂度:

最坏情况下为o(n^2);

最好情况下为:o(n*log2n);

代码:

void quicksort(int left,int right)
{
	int i,j,t,temp;
	if(left > right)
	{
		return;	
	}
	temp = a[left];
	i = left;
	j = right;
	while(i !=j)
	{
		while(a[j]>temp && i<j)
		{
			j--;
		}
	
		while(a[i]>temp && i<j)
		{
			i++;
		}
		if(i<j)
		{
			t=a[i];
			a[i] = a[j];
			a[j] = t;
		}
	}
	a[left] = a[i];
	a[i] = temp;
	quicksort(left,i-1);
	quicksort(i+1,right);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值