ExchangeSort

来源:互联网 发布:验证码java 编辑:程序博客网 时间:2024/06/01 10:11
/*******************************************************************************

冒泡排序(Bubble Sort,台湾译为:泡沫排序、气泡排序)是一种简单的排序算法。
它重复地走访过要排序的数列,一次比较两个项目,如果他们的顺序错误就把他们交换过来。
走访数列的工作是重复地进行直到没有再需要做交换动作,也就是说该数列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换的动作慢慢“浮”到数列的顶端。

冒泡排序对n个项目需要O(n2)的比较次数,且可以原地排序。尽管这个算法是最简单了解和实作的排序算法之一,但它对于少数元素之外的数列排序是很没有效率的。
冒泡排序是与插入排序拥有相等的执行时间,但是两种法在需要的交换动作次数却很大地不同。在最坏的情快,冒泡排序需要O(n2)交换动作,而插入排序只要最多O(n)交换。
冒泡排序通常会对已经排序好的数列拙劣地执行(O(n2)),而插入排序在这个例子只需要O(n)个运算。因此很多现代的算法教科书避免使用冒泡排序,而用插入排序取代之。
冒泡排序如果能在内部回圈第一次执行时,使用一个旗标来表示有无需要交换的可能,也有可能把最好的复杂度降低到O(n)。在这个情况,在已经排序号的数列就无交换的需要。
若在每次走访数列时,把走访顺序和比较大小反过来,也可以些微地改进效率。有时候称为往返排序(Shuttle Sort),因为算法会从数列的一端到另一端之间穿梭往返。

冒泡排序算法的运作如下:
//第一轮得出的结果必然是最大或者最小值
//而插入排序的第一轮排序是得不到最值的,而且随着进行比较的次数可能增多,而冒泡是减少的。


比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
void BubbleSort(int *array, int length){int i, j;int temp;//冒泡,从最低层0逐步比较到length-1for (i = length - 1; i > 0; i--){for (j = 0; j < i; j++)if (array[j] > array[j+1]){temp = array[j];array[j] = array[j+1];array[j+1] = temp;}}}


*******************************************************************************/


/*******************************************************************************

鸡尾酒排序,又被称作双向冒泡排序,是一种从冒泡算法演变成的稳定排序算法,不同于冒泡算法重复的从头到尾比较,鸡尾酒算法交替的从头到尾再从尾到头比较关键字。该算法的性能比标准的冒泡算法稍高。
注意:鸡尾酒算法可以看作是选择算法的一种变体。

鸡尾酒算法在最坏情况下的复杂度为O(n2),如果序列已经近似的排列好,则复杂度会接近O(n)。

双向冒泡排序至于为什么性能会比直接冒泡的性能要高,虽然我感觉都差不多,但是应该是在数学上的概率问题,
也即从头到尾,从尾到头,不断的比较得出最大最小值,在概念上感性是比较优的,还需多多研究。

void CocktailSort(int *array, int length){int i;int temp;    int left = 0, right = length;    int finished;    do    {        finished = 1;        --right;//此循环的结果是,a[right]为最大值        for (i = left; i < right; i++)        {//交换位置,保证a[i]<=a[i+1]            if (array[i] > array[i+1]){                temp = array[i];array[i] = array[i+1];array[i+1] = temp;                finished = 0;//只要进入if就赋为0,表明在争夺right的位置时,有阻力,不是//顺风局            }}//若一次都没有进入过交换位置的if语句表明都时拍好序的,可以直接退出if (finished){return;}//如果进入if则说明,并没有完全排好序finished = 1;//此循环的结果是,a[left]为最小值        for (i = right - 1; i > left; i--)        {//保证a[i]>a[i-1]            if (array[i] < array[i-1]){                temp = array[i];array[i] = array[i-1];array[i-1] = temp;                finished = 0;            }}        ++left;    } while (!finished);//进入过if就表明已经不用再排序了}


*******************************************************************************/

/*******************************************************************************

快速排序(Quicksort)是一种众所周知的排序算法,由C. A. R. Hoare所发展的,以平均效能来说,排序 "n" 个项目要Θ(n log n)次比较。然而,在最坏的效能下,它需要Θ(n2)次比较。
一般来说,快速排序实际上明显地比其他Θ(n log n) 算法更快,因为它的内部回圈(inner loop)可以在大部分的架构上很有效率地被实作出来,且在大部分真实世界的资料,可以决定设计的选择,减少所需时间的二次方项之可能性。

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。步骤如下:
从数列中挑出一个元素,称为 "基准"(pivot)。
重新排叙述列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任ㄧ边)。在这个分割之后,该基准是它的最后位置。这个称为分割(partition)操作。
递回地(recursive)把小于之元素的子数列和大于之元素的子数列排序。
递回的最底部情形,是数列的大小是零或一,也就使永远都已经被排序好了。虽然一直递回下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

//以pivot为基准,从a[high]开始hight递减和pivot进行比较
//从a[low]开始low递增和pivot进行比较
//这个函数的结果是,得到的a以下标low(=high)为界限,前面小于pibot,后面大于pivot

//这就和归并差不多了,都是使用了分治策略,归并是直接就把序列直接就分到2个一组
//然后进行排序,2个一组和2个一组进行合并,变成4个一组,逐步合并的。
//而快速排序是通过一个基准(一般选第一个),进行二分,不断进行二分到最后也就排好序了
//每一组排好序,而组与组之间又是有序的,整个就排好序了

//以pivot为基准,从a[high]开始hight递减和pivot进行比较//从a[low]开始low递增和pivot进行比较//这个函数的结果是,得到的a以下标low(=high)为界限,前面小于pibot,后面大于pivotint Partition(int *array, int low, int high){int pivot_val = array[low];int temp;while (low < high){while (low < high && array[high] >= pivot_val){--high;}temp = array[low];array[low] = array[high];array[high] = temp;while (low < high && array[low] <= pivot_val){++low;}temp = array[high];array[high] = array[low];array[low] = temp;}return low;}void _QuickSort(int *array, int low, int high){int pivot_loc;if (low < high){//这就和归并差不多了,都是使用了分治策略,归并是直接就把序列直接就分到2个一组//然后进行排序,2个一组和2个一组进行合并,变成4个一组,逐步合并的。//而快速排序是通过一个基准(一般选第一个),进行二分,不断进行二分到最后也就排好序了//每一组排好序,而组与组之间又是有序的,整个就排好序了pivot_loc = Partition(array, low, high);_QuickSort(array, low, pivot_loc - 1);_QuickSort(array, pivot_loc + 1, high);}}void QuickSort(int *array, int length){_QuickSort(array, 0, length - 1);}


*******************************************************************************/