【经典排序算法】---基于比较的排序算法

排序算法可以分为两类:

非线性时间比较排序:通过比较来决定元素之间的相对次序,由于其时间复杂度不能突破O(nlogn)。

线性时间非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下届,以线性时间运行。

排序算法分类:

非线性时间比较类排序

       交换排序:冒泡;快排;

       插入排序:简单插入排序;shell;

       选择排序:简单选择;堆排序;

       归并排序:二路归并;多路归并;              

线性时间比较类排序

        基数排序;桶排序;基数排序;

相关概念:

稳定性:排序后相对顺序不变;

不稳定性:排序后相对位置改变

时间复杂度:

空间复杂度:

算法复杂度

排序算法 平均时间复杂度 最好时间复杂度 最差时间复杂度 空间复杂度 稳定性
冒泡排序 O(n^{2}) O(n) O(n^{2}) O(1) 稳定
快速排序 O(n\log n) O(n\log n) O(n^{2}) O(n\log n) 不稳定
简单选择 O(n^{2}) O(n^{2}) O(n^{2}) O(1) 不稳定
堆排序 O(n\log n) O(n\log n) O(n\log n) O(1) 不稳定
简单插入 O(n^{2}) O(n) O(n^{2}) O(1) 稳定
shell排序 O(n^{1.3}) O(n) O(n^{2}) O(1) 不稳定
归并排序 O(n\log n) O(n\log n) O(n\log n) O(n) 稳定

 

1、冒泡排序

算法思想:重复走访要排序的数列,一次比较两个元素,如果它们的顺序错误就将它们交换过来,走访数列的工作是重复的进行指导没有再需要交换,即数列已经排序完成。

算法描述:

比较相邻的元素,如果第一个比第二个大,就交换它们两个。

对每一对相邻元素做相同的工作,从开始第一对到结尾的最后一对,这样在最后的元素就是最大的数。

针对所有元素重复以上步骤,对已经排序的元素不再进行排序,重复,直至排序完成。


public class BubbleSort {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		 int[] arr= new int[] {2,9,0,5,3,8,4};
		 bubblesort(arr);
		 for(int i=0;i<arr.length;i++)
			 System.out.print(arr[i]+"\t");
		
	}
	
	public static void bubblesort(int[] arr) {
		int len=arr.length;
		for(int i=0;i<arr.length;i++) {
			for(int j=0;j<arr.length-i-1;j++) {
				if (arr[j]>arr[j+1]) {
					int temp = arr[j];
					arr[j]=arr[j+1];
					arr[j+1]=temp;
				}
			}
		}
	}

}

选择排序

算法思想:首先在未排序序列中找到最小(大)的元素,存放在排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放在已排序序列的末尾,以此类推,直到所有元素都排序完毕。

算法描述

初始状态:无序区为R[1..n],有序区为空;

第i趟排序(i=1,2,....n-1)开始时,当前有序区和无序区分别为R[1..i-1]和R[i...n],然后从无序区选取值最小的元素为R[k],将它与无序区的第一个记录R[i]交换,这样有序区就变成了R[1....i],无序区为R[i+1,.....n]

重复n-1趟,数组有序化

public static void selectsort(int[] arr) {
		int len = arr.length;
		for(int i=0;i<len-1;i++) {
			int minindex=i;
			for(int j=i+1;j<len;j++) {			
				if (arr[j]<arr[minindex]) {
					minindex=j;
				}
			}
			int temp=arr[i];
			arr[i]=arr[minindex];
			arr[minindex]=temp;
		}	
	}

插入排序

算法思想:对数组中的每一个元素,在已排序序列中从后向前扫描,查找到相应的位置后插入。

算法描述:

从第一个元素开始,该元素已经排好序;

取出下一个元素,在已经排好序的序列中从后向前扫描;

如果该元素(已排序)大于新元素,该元素移动到下一个位置;

重复,直到找到已排序的元素小于等于新元素的位置;

将新元素插入到该位置后。

public static void insertsort(int[] arr) {
		int len=arr.length;
		for(int i=1;i<len;i++) {
			int index=i;
			int temp=arr[i];
			for(int j=i;j>0;j--) {
				if (arr[i]<arr[j-1]) {
					index=j-1;
				}
			}
			for(int j=i;j>index;j--) {
				arr[j]=arr[j-1];
			}
			arr[index]=temp;
		}
	}

4、希尔排序(shell)

算法思想:缩小增量排序

算法描述:

选择一个增量序列t1、t2、......tk,其中ti>tj(i<j),tk=1;

按增量序列个数k,对序列进行k趟排序

每趟排序,根据对应的增量ti,将序列分割成若干个长度为m的子序列,分别对各子表进行直接插入排序,当增量因子为1时,整个序列作为一个表来处理,表长度为整个序列的长度。

5、快速排序

算法思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

算法描述:

从数据中挑出一个元素作为基准(pivot);(每次选择分区中最左边的元素作为基准)

重新排序数组,所有比基准值小的放在基准前面,所有比基准值大的元素放在基准元素后面,在这个分区退出之后,该基准就位于正确地位置上;

递归的把小于基准值元素的子数列和大于基准值元素的子数列排序;

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

6、堆排序

算法思想:利用堆这一数据结构所设计的一种排序算法,堆是一个近似完全二叉树的结构,并满足堆的性质,即结点的键值或者索引总是小于(或者大于)它的父结点。

算法描述:

1、将待排序列初始化为最大堆,并将堆顶元素R[1]删除,和最后一个元素R[n]进行交换;

2、将新的堆调整为最大堆,并重复操作1,直到整个排序过程完成;

private static void buildMaxHeap(int[] arr,int len) {//建立最大堆
		for(int i=len/2;i>=0;i--) {
			heapify(arr,i,len);
		}
	}
	private static void heapify(int[] arr,int i,int len) {//调整堆
		int left=2*i+1;
		int right=2*i+2;
		int largest = i;
		if (left<len&&arr[left]>arr[largest]) {
			largest=left;
		}
		if (right<len&&arr[right]>arr[largest]) {
			largest=right;
		}
		if (largest!=i) {
			swap(arr,i,largest);
			heapify(arr, largest,len);
		}
	}
	private static void swap(int[] arr,int i,int j) {//元素交换
		int temp=arr[i];
		arr[i]=arr[j];
		arr[j]=temp;
	}
	private static void heapsort(int[] arr) {
		int len=arr.length;
		buildMaxHeap(arr,len);
		for(int i=arr.length-1;i>0;i--) {
			swap(arr, 0, i);
			len--;
			heapify(arr, 0,len);
		}
	}

猜你喜欢

转载自blog.csdn.net/m0_38103546/article/details/82851676