排序算法分析以及源码

 

 

排序算法

描述

时间复杂度

空间复杂度

稳定性

说明

冒泡排序

正反循环

ON*N

O1

 

插入排序

慢慢有序

ON*N

O1

 

归并排序

分治

ON*logmN

ON

 

基数排序

求余

ON*logmN

O11N

LSD MSD

选择排序

选择min or max

ON*N

O1

 

快速排序

分治(直接两边大小区分)

ON*log2N

O1

 

希尔排序

三重循环

ON*log2N

O1

有序的序列效率很高

堆排序

构造堆顶,交换

ON*log2N

O1

均性能较接近于最坏性能


public class Sort {
	/**
	 * Utils for swap and print
	 */
	public static void swap(int[] data, int indexOne, int indexTwo) {
		int temp = data[indexOne];
		data[indexOne] = data[indexTwo];
		data[indexTwo] = temp;
	}

	public static void print(int[] data) {
		System.out.println("--------------------------------");
		for (int i = 0; i < data.length; i++) {
			System.out.print(data[i]+", ");
		}
		System.out.println();
	}
	/**
	 * 冒泡排序
	 * 			(稳定)
	 * 每次通过交换,将最大或者最小的移动到前面
	 */
	public static void bubbleSort(int[] data) {
		for (int i = 0; i < data.length; i++) {
			for (int j = data.length - 1; j > i; j--) {
				if (data[j] < data[j - 1]) {
					swap(data, j, j - 1);
				}
			}
		}
	}
	/**
	 * 插入排序
	 * 			(稳定)
	 * 处理顺序是:1个元素有序,2个元素有序,3个元素有序。。。。
	 */
	public static void insertSort(int[] data) {
		for (int i = 1; i < data.length; i++) {
			for (int j = 0; j < i; j++) {
				if (data[j] > data[i]) {
					swap(data, j, i);
				}
			}
		}
	}

	/**
	 * 归并排序 (2路归并)
	 * 			(稳定)
	 * 要点:
	 * 1. int mid = (last+first)/2;
	 * 2. i < last+1
	 */
	public static void mergeSort(int[] data, int first, int last){
		if (first >= last) {
			return;
		}
		int mid = (last+first)/2;
		mergeSort(data, first, mid);
		mergeSort(data, mid + 1, last);
		merge(data, first, mid, last);
	}
	public static void merge(int[] data, int first, int mid, int last){
		int[] temp = new int[last - first + 1];
		
		int begin1 = first;
		int end1 = mid;
		int begin2 = mid +1 ;
		int end2 = last;
		
		int k = 0;
		while (begin1 <= end1 && begin2 <= end2 ) {
			if (data[begin1] < data[begin2]) {
				temp[k] = data[begin1];
				begin1 ++ ;
			}else {
				temp[k] = data[begin2];
				begin2 ++ ;
			}
			k++;
		}
		while (begin1 <= end1) {
			temp[k++] = data[begin1++];
		}
		while (begin2 <= end2) {
			temp[k++] = data[begin2++];
		}
		for (int i = first; i < last+1; i++) {
			data[i] = temp[i-first];
		}
	}
	
	/**
	 * 基数排序 
	 * 			(稳定)
	 * 要点:
	 * 1. temp空间的开辟
	 * 2. 计数空间的开辟
	 * 3. 如何通过radix求取remainder
	 */
	public static void radixSort(int[] data,int depth){
		int radix = 1 ;
		while ( radix <=depth ) {
			int[][] temp = new int[10][data.length];
			int[] count = new int[10];
			for (int i = 0; i < count.length; i++) {
				count[i] = -1;			
			}
			for (int i = 0; i < data.length; i++) {
				int remainder = (data[i]/radix)%10;
				if (count[remainder] == -1) {
					count[remainder] = 0;
				}
				temp[remainder][count[remainder]] = data[i];
				count[remainder]++;
			}
			int k = 0;
			for (int i = 0; i < temp.length; i++) {
				for (int j = 0; j < count[i]; j++) {
					data[k] = temp[i][j];
					k++;
				}
			}
			radix = radix*10;
		}
	}
	
	/**
	 * 选择排序
	 * 			(不稳定)
	 * 每次找到最大(或者最小的),放到前面
	 */
	public static void selectSort(int[] data) {
		for (int i = 0; i < data.length; i++) {
			int min = i;
			for (int j = i + 1; j < data.length; j++) {
				if (data[j] < data[min]) {
					min = j;
				}
			}
			swap(data, min, i);
		}
	}
	/**
	 * 快速排序(改进的冒泡排序)
	 * 			(不稳定)
	 * 循环递归
	 * 要点:
	 * 1. 嵌套的while循环条件 	i<right , j>left
	 * 2. 将key元素交换到正确的位置(和j所在元素交换)
	 */
	public static void quickSort(int[] data, int left, int right) {
		if (left >= right) {
			return;
		}
		int key = data[left];
		int i = left + 1;
		int j = right;
		while(true){
			while (data[j] > key && j > left) j-- ;
			if (i < j) {
				swap(data, i, j);
			}
			while (data[i] < key && i < right) i++ ;
			if (i < j) {
				swap(data, i, j);
			}
			if (i >= j) {
				break;
			}
		}
		swap(data, left, j);
		quickSort(data,left,j-1);
		quickSort(data,j+1,right);
	}
	
	/**
	 * 希尔排序(改进的插入排序)
	 * 			(不稳定)
	 * 三重循环
	 */
	public static void shellSort(int[] data) {
		int dataLength = data.length/2;
		while (dataLength != 0) {
			for (int i = 0; i < dataLength; i++) {
				//所有的数字为i ,i+dataLength,i+2*dataLength......
				for (int j = 1; j < data.length; j = j+dataLength) {
					for (int k = 0; k < j; k = k+dataLength) {
						if (data[k] > data[j]) {
							swap(data, j, k);
						}
					}
				}
			}
			dataLength = dataLength/2;
		}
	}
	
	/**
	 * 堆排序
	 * 			(不稳定)
	 * 从小到大,就构造大顶堆。
	 * 要点:
	 * 1. 半次循环,将最大的数字弄到堆顶。
	 * 2. 构造堆的长度不断减小。
	 */
	public static void heapAdjust(int[] data, int i, int length){
		int parent = i;
		int child = 2*i + 1;
		while (child < length) {
			if (child+1 < length && data[child] < data[child+1]) {
				child ++ ;
			}
			if (data[parent] < data[child]) {
				swap(data, parent, child);
				parent = child;
				child = 2*parent + 1;
			}else {
				break;
			}
		}
	}
	public static void heapSort(int[] data, int length){
		for (int i = length/2 -1 ; i >= 0; i--) {
			heapAdjust(data, i , length);
		}
		for (int i = length - 1; i >= 1 ; i--) {
			swap(data, 0, i);
			heapAdjust(data,0,i);
		}
	}
	
	public static void main(String[] args) {
		int[][] datas = { 
				{ 1, 2, 3, 4, 5 }, 
				{ 5, 4, 3, 2, 1 },
				{ 5, 1, 3, 4, 2 }, 
				{ 10, 233, 3222, 411, 532 }, 
				{ 1 } 
			};
		for (int i = 0; i < datas.length; i++) {
			int[] data = datas[i];
			radixSort(data,1000);
			print(data);
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值