4种排序算法

1、冒泡排序

  冒泡排序其实是基于“交换”。每次从第一个记录开始,一、二两个记录比较,大的往后放,二三两个记录比较...依次类推,这就是一趟冒泡排序。每一趟冒泡排序后,无序序列中值最大的记录冒到序列末尾,所以称之为冒泡排序

function BubbleSort(&$_arr){
	$len=count($_arr);     //外循环控制轮数
	for($j=$len;$j>0;$j--){         //控制比较次数
		for($i=0;$i<$j-1;$i++){
			if($_arr[$i]>$_arr[$i+1]){
				$temp=$_arr[$i];
				$_arr[$i]=$_arr[$i+1];
				$_arr[$i+1]=$temp;
			}
		}
	}
}

效率分析

相对于简单选择排序,冒泡排序交换次数明显更多。它是通过不断地交换把最大的数冒出来。

冒泡排序平均时间和最坏情况下(逆序)时间为o(n^2),最佳情况下虽然不用交换,但比较的次数没有减少,时间复杂度仍为o(n^2)。此外冒泡排序是稳定的

2、选择排序

  给定待排序序列A[ 1......n ] ,选择出第i小元素,并和A[i]交换,这就是一趟简单选择排序。固定值、然后交换索引

function SelectSort(&$_arr){
    $len = count($_arr);
    for($i=0; $i<$len; $i++){
        $k = $i;
        for($j=$i+1; $j<$len; $j++){
            if ($_arr[$k] > $_arr[$j])
                $k = $j;
            if ($k != $i){
                $tmp = $_arr[$i];
                $_arr[$i] = $_arr[$k];
                $_arr[$k] = $tmp;
             }
         }
     }
}

性能分析

  简单选择排序所需进行记录移动的操作次数较少,这一点上优于冒泡排序,最佳情况下(待排序序列有序)记录移动次数为0,最坏情况下(待排序序列逆序)记录移动次数n-1。外层循环进行了n-1趟选择,第i趟选择要进行n-i次比较。每一趟的时间:n-i次的比较时间+移动记录的时间(为一常数0或1,可以忽略)。总共进行了n-1趟。忽略移动记录的时间,所以总时间为(n-1)*(n-i)=n^2-(i+1)*n+i。时间复杂度为O(n^2)。不管是最坏还是最佳情况下,比较次数都是一样的,所以简单选择排序平均时间、最坏情况、最佳情况时间复杂度都为O(n^2)

直接选择排序是一个就地排序,直接选择排序是不稳定的

3、插入排序

  给定待排序序列A[ 1.....n ],现假设A[1...i]已经有序,那么我们取出A[i+1]插入到序列A[1...i].这样有序序列记录数就增加了1.如此重复上述操作,不断取出记录插入有序序列,直到A[n]插入到有序序列,排序完成

  从有序序列的最后一个元素开始查找,边查找边移动元素,而不是先找到插入位置再移动元素,这样提高了效率。

function InsertSort(&$_arr){
	$len = count($_arr);
	for($i=1; $i<$len; $i++){
		$tmp = $_arr[$i];
		$j = $i-1;

		while($_arr[$j] > $tmp && $j>=0){
			$_arr[$j+1] = $_arr[$j];
			$_arr[$j] = $tmp;
			$j--;

		}
	}
}

效率分析

  容易看出,要插入的记录个数为n-1,其中关键字的比较次数和记录移动次数是依赖于给出的待排序序列是否基本有序。在最佳情况下(待排序序列有序),比较次数和移动次数时间为o(1),所以时间复杂度为o(n).在最坏情况下(待排序序列逆序)和平均时间均为o(n^2).从上述分析中可以看出,直接插入排序适合记录数比较少、给定序列基本有序的情况。熟悉了排序过程我们发现,直接插入排序是一种稳定的原地排序算法

4、快速排序

  快速排序是冒泡排序的一种改进,冒泡排序排完一趟是最大值冒出来了,那么可不可以先选定一个 值,然后扫描待排序序列,把小于该值的记录和大于该值的记录分成两个单独的序列,然后分别对这两个序列进行上述操作。这就是快速排序,我们把选定的那个值 称为枢纽值,如果枢纽值为序列中的最大值,那么一趟快速排序就变成了一趟冒泡排序

function QuickSort($_arr){
	$len=count($_arr);
	if($len <= 1) return $_arr;

	$base = $_arr[0];
	$left_arr =$right_arr=array();

	for($i=1; $i<$len; $i++){
		if($_arr[$i]<= $base){
		  $left_arr[]=$_arr[$i];
		}else{
		  $right_arr[]=$_arr[$i];
		}
	}

	$left_arr=QuickSort($left_arr);
	$right_arr=QuickSort($right_arr);

	$arr=array_merge($left_arr, array($base), $right_arr);
	return $arr;
}

效率分析

  最佳情况下,每次划分都是对称的,由于枢纽值不再考虑,所以得到的两个子问题的大小不可能大于n/2,同时一趟快速排序时间为o(n),所以运行时间递归表达式:T(n)<=2T(n/2)+o(n)。这个递归式的解法请参考下一篇博客中归并排序效率分析。其解为T(n)=o(n*logn)。

  最坏情况下,每次划分都很不对称,T(n)=T(n-1)+o(n),可以用递归树来解,第i层的代价为n-i+1.总共有n层。把每一层代价加起来有n-1个n相加。所以这个递归式的解为T(n)=o(n^2),此时就是冒泡排序。

还有两个概念要了解一下

1. 内排序和外排序

内排序,参加排序的数据量不大,在排序过程中可以将所有参加排序的数据存放在内存中处理的排序方法。

外排序,参加排序的数据量很大,以至于内存不足以一次存放全部数据,在排序过程中需要通过内存与外存之间的数据交换来达到排序目的的排序方法。

2. 稳定性排序与非稳定性排序

参加排序的项称为排序码或者排序项。

这个概念是针对的是有多个相同的排序项参加排序的情况。

若采用排序方法排序后这些相同的排序项的相对位置与排序之前保持不变,则称此排序方法是稳定性排序,否则为非稳定性排序。

例如,参加排序的依次是:a1 = 3, a2 = 6, a3 = 18, a4 = 3, a5 = 18;

若是稳定性排序,则排序结果一定是:

a1 = 3, a4 = 3, a2 = 6, a3 = 18, a5 = 18;

若是非稳定性排序,则排序结果可能会是:

a4 = 3, a1 = 3, a2 = 6, a3 = 18, a5 = 18;

这样a1 和a4 的相对位置改变。

时间: 2024-10-11 12:18:59

4种排序算法的相关文章

八种排序算法

最近一段时间自己在研究各种排序算法,于是自己写了一个八种排序算法的集合: /************************************************************************* > Copyright (c)2014 stay hungry,stay foolish !!! > File Name: sort.cpp > Author: kanty > Mail: [email protected] > Created Time:

几种排序算法比较

图解数据结构(10)——排序 十四.排序(Sort) http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html <Thinking in Algorithm>12.详解十一种排序算法 http://blog.csdn.net/speedme/article/details/23021467

数据结构中的7种排序算法

数据结构中的7种排序算法 排序是将一个记录的任意序列重新排列成一个按键值有序的序列. 时间复杂度主要考虑元素的移动次数. 结构如下: 1.直接插入排序 1,定义:依次将待排序序列中的每一个记录插入到一个已经排好序的序列中,直到全部记录都排好序. 2,时间复杂度:在最好情况下,待排序序列为正序,时间复杂度为O(n):最坏情况下,待排序序列为逆序,时间复杂度为O(n^2);平均情况下,时间复杂度为O(n^2). 3,空间复杂度:O(1). public static void insertSort(

总结N种排序算法及实现

排序算法是一个简单的问题,但在此问题上却有大量的研究!当前的排序算法通常按照如下四个方面进行分类(或是评价): 1.时间复杂度:一个排序算法的理想性能是O(n).一般而言,好的性能O(nlogn),坏的性能O(n2). 2.空间复杂度(内存使用量) 3.稳定性:稳定的排序算法会让原本有相等键值的记录维持原本的相对次序. 4.排序方式:插入.交换.选择.合并等 一.冒泡排序:这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端. 步骤:1.比较相邻的两个元素,如果第一个比第二个大,就

八种排序算法(内部排序)

八种排序算法很长时间没有使用了,今天做一个总结,方便以后自己用的时候参考. 这八种排序算法都是内部算法,这八种排序算法分别是: 1. 插入排序 1)直接插入排序 2)希尔排序 2.选择排序 1)简单选择排序 2)堆排序 3.交换排序 1)冒泡排序 2)快速排序 4.归并排序 5.基数排序 一.直接插入排序 将一个记录插入到已经排好序的有序表中,从而得到一个新的.记录数增1的有序表.在实际操作中,先将序列的第一个记录看成是一个有序的子序列,然后从第二个.第三个.……记录逐个进行插入,直至整个序列有

12种排序算法:原理、图解、动画视频演示、代码以及笔试面试题目中的应用

出处:http://blog.csdn.net/han_xiaoyang/article/details/12163251. 声明:版权所有,转载请注明出处,谢谢. 0.前言 从这一部分开始直接切入我们计算机互联网笔试面试中的重头戏算法了,初始的想法是找一条主线,比如数据结构或者解题思路方法,将博主见过做过整理过的算法题逐个分析一遍(博主当年自己学算法就是用这种比较笨的刷题学的,囧),不过又想了想,算法这东西,博主自己学的过程中一直深感,基础还是非常重要的,很多难题是基础类数据结构和题目的思想综

四种排序算法PHP实现类

四种排序算法的PHP实现:1) 插入排序(Insertion Sort)的基本思想是: 每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止. 2) 选择排序(Selection Sort)的基本思想是: 每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,直到全部记录排序完毕. 3) 冒泡排序的基本思想是: 两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止. 4) 快速排序实质上和

经典的两种排序算法

一.冒泡排序 int temp = 0; for (int j = 1; j < a.Length; j++) { for (int i = 0; i < a.Length - j; i++)//内循环,每走一趟会把最小值放到最后 { if (a[i] < a[i + 1]) { temp = a[i]; a[i] = a[i + 1]; a[i + 1] = temp; } } } 二.选择法排序 int min; for (int j = 0; j< a.Length; j++

几种排序算法的C++实现——快速排序、堆排序、基数排序

排序算法是非常常见的面试笔试问题,考查的一个人的基本功,本文将一些排序做了C++的实现,就当是做个学习总结吧. 1.快速排序 快速排序的中心是填坑法,取一个数(这里选取第一个数)作为基准数temp,从队尾开始寻找第一个比基准数小的数a[j],交换a[j]和temp,然后队首开始查找第一个比temp大的数a[i],交换之,遍历的结果是当i>=j时,temp左边的数都小于temp,后边的数都大于temp,这个有点像归并排序.最后利用递归调用完成排序,代码如下: 1 void QuickSort(in

算法—比较两种排序算法:选择排序和插入排序

现在我们已经实现了两种排序算法,我们很自然地想知道选择排序和插入排序哪种更快.这里我们第一次用实践说明我们解决这个问题的办法. 性质:对于随机排序的无重复主键的数组,插入排序和选择排序的运行时间是平方级别的,两者之比应该是一个较小的常数. 例证:这个结论在过去的半个世纪中已经在许多不同类型的计算机上经过了验证.在1980年本书第一版完成之时插入排序就比选择排序快一倍,现在仍然是这样,尽管那时这些算法将10万条数据排序需要几个小时而现在只需要几秒钟.在你的计算机上插入排序也比选择排序快一些吗?可以