各种排序算法总结

原创 2013年12月01日 20:41:19

(注:以下所讲排序,以升序排序为例!)

选择排序:

作者思路:在一组数中,选择第一个数标记为最小值,在剩下的数中找比它小的数,若找到则交换两数,标记新的"最小值",然后继续往下找,这样一趟下来就可以找到一组数中第二小的值,第二次以第二个数作为最小值,如此循环下去。这是最简单、最基础的一种排序算法。


例子:13,34,18,9,12,34,100

第一次(i=0),以13为最小值,第一次算法结束:9,34,18,13,12,100

第二次(i=1),以34作为最小值,(18比它小,交换得)9,18,34,13,12,100——>(13比18小,交换)9,13,34,18,12,100——>结束得:9,12,34,18,13,100,此时 12已经是真正的次最小值。往后找不到比它还小的。

第三次(i=2),以34做为最小值,继续执行

。。。


时间复杂度: O(n * n);

代码:

void Swap(int a[], int i, int j)
{
	int tmp = a[i];
	a[i] = a[j];
	a[j] = tmp;
}

void SelectSort(int a[], int len) //O(n * n)
{
	int i = 0;
	int j = 0;
	int min = 0;
	
	for(i=0; i<len; i++)
	{	
		min = a[i];
		
		for(j=i+1; j<len; j++)
		{
			if(a[j] < min)
			{
				Swap(a, i, j);
			}
			min = a[i];
		}
	}
}

插入排序:

作者思路:插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。 

时间复杂度:O(n * n)


代码:

void InertionSort(int array[], int len) // O(n*n)
{
    int i = 0;
    int j = 0;
    int k = -1;
    int temp = -1;
    
    for(i=1; i<len; i++)
    {
        k = i;
        temp = array[k];
        
        for(j=i-1; (j>=0) && (array[j]>temp); j--)
        {
            array[j+1] = array[j];
            k = j;
        }
        
        array[k] = temp;
    }
}

冒泡排序:

作者思路:将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。


代码:

void BubbleSort(int a[], int len) //O(n * n)
{
	int i = 0;
	int j = 0;
	int k = 1;//标记,避免不必要的循环。
	
	for(i=0; i<len && k; i++)
	{	
		k = 0;
		
		for(j=len-1; j>i; j--)
		{
			if(a[j] < a[j-1])
			{
				Swap(a, j, j-1);
				k = 1;
			}
		}
	}
}

总结:上述三种排序算法都比较基础,也不难,关键要理解其思想;三种算法都是稳定算法(ps:什么是稳定算法,比如一组数中有两个一样的数 9,9*(加*以示区分) 排序后,两者的顺序不会变动 这样的算法是稳定的 )。


快速排序:

快速排序是一种排序算法,对包含n个数的输入数组,平均时间为O(nlgn),最坏情况是O(n^2)。
通常是用于排序的最佳选择。因为,基于比较的排序,最快也只能达到O(nlgn)。

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

步骤为:

  1. 从数列中挑出一个元素,称为 "基准"(pivot),
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。


代码:

int Partation(int a[], int low, int high)
{
	int val = a[low];
	
	while(low < high)
	{
		while( (low < high) && (a[high] >= val) )
		{
			--high;
		}
		a[low] = a[high];
		
		while( (low < high) && (a[low] <= val) )
		{
			++low;
		}
		a[high] = a[low];
	}
	a[low] = val;
	
	return low;
}

void QuickSort(int a[], int low, int high) //O(n * n)
{
	int pos = 0;
	
	if(low < high)
	{
		pos = Partation(a, low, high);
		QuickSort(a, low, pos-1);
		QuickSort(a, pos+1, high);
	}
}


感想:排序算法很精巧,真佩服当初能想出那种算法的计算机界大牛,自己还差很远。

版权声明:本文为博主原创文章,未经博主允许不得转载。

排序算法总结

  • 2015年07月04日 19:19
  • 390KB
  • 下载

排序算法总结

  • 2014年01月21日 13:52
  • 12KB
  • 下载

八大排序算法总结与java实现

原文链接: 八大排序算法总结与java实现 - iTimeTraveler 概述因为健忘,加上对各种排序算法理解不深刻,过段时间面对排序就蒙了。所以决定对我们常见的这几种排序算法进行统一总结,强行学习...

8个常见数据结构排序算法总结

  • 2013年11月15日 21:10
  • 23KB
  • 下载

各种排序算法总结

  • 2013年03月01日 13:21
  • 780B
  • 下载

总结5种比较高效常用的排序算法

1 概述     本文对比较常用且比较高效的排序算法进行了总结和解析,并贴出了比较精简的实现代码,包括选择排序、插入排序、归并排序、希尔排序、快速排序等。算法性能比较如下图所示:   2 选...
  • hl_java
  • hl_java
  • 2017年05月18日 20:42
  • 147

常用排序算法总结

  • 2013年06月01日 15:55
  • 4KB
  • 下载

各种排序算法时间复杂度和稳定性总结【转】

转载自:http://blog.csdn.net/lockedstar/article/details/5699388 原文:blog.chinaunix.net/u/1222/showart_318...
  • lanximu
  • lanximu
  • 2013年09月23日 17:03
  • 647

C-C++排序算法总结

  • 2010年03月27日 13:06
  • 3KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:各种排序算法总结
举报原因:
原因补充:

(最多只允许输入30个字)