快排序和堆排序,最小堆、最大堆

1)分类: java

1)插入排序(直接插入排序、希尔排序)   算法

2)交换排序(冒泡排序、快速排序) 数组

3)选择排序(直接选择排序、堆排序) ui

4)归并排序 spa

5)分配排序(箱排序、基数排序) code

所需辅助空间最多:归并排序 排序

所需辅助空间最少:堆排序 递归

平均速度最快:快速排序 it

不稳定:快速排序,希尔排序,堆排序。 io

1)选择排序算法的时候

1.数据的规模 ;  2.数据的类型 ;  3.数据已有的顺序  
通常来讲,当数据规模较小时,应选择直接插入排序或冒泡排序。任何排序算法在数据量小时基本体现不出来差距。考虑数据的类型,好比若是所有是正整数,那么考虑使用桶排序为最优。  考虑数据已有顺序,快排是一种不稳定的排序(固然能够改进),对于大部分排好的数据,快排会浪费大量没必要要的步骤。数据量极小,而起已经基本排好序,冒泡是最佳选择。咱们说快排好,是指大量随机数据下,快排效果最理想。而不是全部状况。

快速排序

快 速排序是对冒泡排序的一种改进。它的基本思想是:经过一躺排序将要排序的数据分割成独立的两部分,其中一部分的全部数据都比另一不部分的全部数据都要 小,而后再按次方法对这两部分数据分别进行快速排序,整个排序过程能够递归进行,以此达到整个数据变成有序序列。最坏状况的时间复杂度为O(n2),最好 状况时间复杂度为O(nlog2n)。

   假设要排序的数组是A[1]……A[N],首先任意选取一个数据(一般选用第一个数据)做为关键数据,而后将全部比它的数都放到它前面,全部比它大的数都放到它后面,这个过程称为一躺快速排序。一趟快速排序的算法是:

1)、设置两个变量I、J,排序开始的时候I:=1,J:=N;

2)以第一个数组元素做为关键数据,赋值给X,即X:=A[1];

3)、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,二者交换;

4)、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,二者交换;

5)、重复第三、4步,直到I=J;

例如:待排序的数组A的值分别是:(初始关键数据X:=49)

                  A[1]    A[2]    A[3]    A[4]    A[5]     A[6]    A[7]:

                    49       38      65      97      76      13       27

进行第一次交换后: 27       38      65      97      76      13       49

                  ( 按照算法的第三步从后面开始找)

进行第二次交换后: 27       38      49      97      76      13       65

                 ( 按照算法的第四步从前面开始找>X的值,65>49,二者交换,此时I:=3 )

进行第三次交换后: 27       38      13      97      76      49       65

( 按照算法的第五步将又一次执行算法的第三步从后开始找)

进行第四次交换后: 27       38      13      49      76      97       65

( 按照算法的第四步从前面开始找大于X的值,97>49,二者交换,此时J:=4 )

     此时再执行第三步的时候就发现I=J,从而结束一躺快速排序,那么通过一躺快速排序以后的结果是:27       38      13      49      76      97       65,即因此大于49的数所有在49的后面,因此小于49的数所有在49的前面。

     快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行相似的快速排序,从而完成所有数据序列的快速排序,最后把此数据序列变成一个有序的序列,根据这种思想对于上述数组A的快速排序的全过程如图6所示:

初始状态                       {49    38    65    97    76    13    27}   

进行一次快速排序以后划分为     {27    38    13}    49 {76    97    65}

分别对先后两部分进行快速排序   {13}   27   {38}

                               结束        结束   {49   65}   76   {97}

                                                   49 {65}        结束

                                                       结束

                         图6   快速排序全过程

/**
 * 快速排序实现算法
 * @author Administrator
 */
public class SortTest {
		/**
		 * @param args
		 */
		public static void main(String[] args) 
		{
			// TODO 自动生成方法存根
			quicksort qs = new quicksort();
			int data[] = {44,22,2,32,54,22,88,77,99,11};
			qs.data = data;
			qs.sort(0, qs.data.length-1);
			qs.display();
		}
	}

	class quicksort
	{
		public int data[];
		
		/*分割、分开*/
		private int partition(int sortArray[],int low,int hight)
		{
			int key = sortArray[low];
			while(low<hight)
			{
				while(low<hight && sortArray[hight]>=key)
					hight--;
				sortArray[low] = sortArray[hight];
				
				while(low<hight && sortArray[low]<=key)
					low++;
				sortArray[hight] = sortArray[low];
			}
			sortArray[low] = key;
			return low;
		}
		
		public void sort(int low,int hight)
		{
			if(low<hight)
			{
				int result = partition(data,low,hight);
				sort(low,result-1);
				sort(result+1,hight);
			}
			
		}
		
		public void display()
		{
			for(int i=0;i<data.length;i++)
			{
				System.out.print(data[i]);
				System.out.print(" ");
			}
		}
	}



堆排序:首先,数组里面用层次遍历的顺序放一棵彻底二叉树。从最后一个非终端结点往前面调整,直到到达根结点,这个时候除根节点之外的全部非终端节点都已经知足堆得条件了,因而须要调整根节点使得整个树知足堆得条件,因而从根节点开始,沿着它的儿子们往下面走(最大堆沿着最大的儿子走,最小堆沿着最小的儿子走)。主程序里面,首先从最后一个非终端节点开始调整到根也调整完,造成一个heap, 而后将heap的根放到后面去(即:每次的树大小会变化,可是 root都是在1的位置,以方便计算儿子们的index,因此若是须要升序排列,则要逐步大顶堆。由于根节点被一个个放在后面去了。降序排列则要创建小顶堆)

相关文章
相关标签/搜索