算法性能对比

插入排序
直接插入排序
- 思想
- 实现思路:初始构建有序区,对于无序区的数据,在有序序列中从后向前扫描,找到相应位置并插入。
- 说明:每趟排序产生的有序区不一定是全局有序区。
- 实现
public class InsertSort {
public static int[] insertSort(int[] arrays){
if(arrays == null || arrays.length < 2){
return arrays;
}
int tmp;
for (int i = 1; i < arrays.length; i++) {
tmp = arrays[i];
int j;
for (j = i-1;j >= 0;j--){
if(tmp >= arrays[j]) break;
arrays[j+1] = arrays[j];
}
arrays[j+1] = tmp;
}
return arrays;
}
public static void main(String[] args) {
int[] arrays = {8,4,6,1,5,3,9,2,7,0};
arrays = insertSort(arrays);
System.out.println(Arrays.toString(arrays));
}
}
希尔排序
- 思想
- 实现思路:实际上是一种分组插入方法。先将整个待排序列分割成若干子序列分别进行直插排序、待整个序列基本有序以后,再对全体序列进行直插排序。
- 说明:每趟排序产生的有序区不一定是全局有序区。
- 实现
public class HillSort {
public static int[] hillSort(int[] arrays){
int increment = arrays.length/2;
int tmp;
while (increment != 0){
for (int i = increment; i < arrays.length; i++) {
tmp = arrays[i];
int j;
for (j = i-increment; j >= 0; j -= increment) {
if(tmp >= arrays[j]){
break;
}
arrays[j+increment] = arrays[j];
}
arrays[j+increment] = tmp;
}
increment = increment>>1;
}
return arrays;
}
public static void main(String[] args) {
int[] arrays = {8,4,6,1,5,3,9,2,7,0};
System.out.println(Arrays.toString(hillSort(arrays)));
}
}
选择排序
简单选择排序
- 思想
- 排序思路:还是分为有序区和无序区,第一次默认都是无序区,每次排序把无序区里最小的元素换至无序区的第一位置,然后将其划入有序区,以此类推。
- 说明:每趟产生的有序区一定是全局有序区,因为每趟都能把一个元素归位。
- 优化:每次归位最小、最大两个元素。
- 实现
public class SelectSort {
public static int[] selectSort(int[] arrays){
if(arrays == null || arrays.length == 0){
return arrays;
}
int index;
int tmp;
for (int i = 0; i < arrays.length; i++) {
index = i;
for (int j = i+1;j < arrays.length;j++){
if(arrays[index] >= arrays[j]){
index = j;
}
}
tmp = arrays[i];
arrays[i] = arrays[index];
arrays[index] = tmp;
}
return arrays;
}
public static int[] optSelectSort(int[] arrays){
if(arrays == null || arrays.length == 0){
return arrays;
}
int minIndex;
int maxIndex;
int tmp;
for (int i = 0; i < arrays.length>>1; i++) {
minIndex = i;
maxIndex = i;
for (int j = i+1;j < arrays.length-i;j++){
if(arrays[minIndex] > arrays[j]){
minIndex = j;
continue;
}
if(arrays[maxIndex] < arrays[j]){
maxIndex = j;
}
}
tmp = arrays[i];
arrays[i] = arrays[minIndex];
arrays[minIndex] = tmp;
if(arrays[i] == arrays[maxIndex]){
maxIndex = minIndex;
}
tmp = arrays[arrays.length-1-i];
arrays[arrays.length-1-i] = arrays[maxIndex];
arrays[maxIndex] = tmp;
}
return arrays;
}
public static void main(String[] args) {
int[] arrays = {8,4,6,1,5,3,9,2,7,0};
int[] arrays1 = {8,4,6,1,5,3,9,2,7,0};
System.out.println(Arrays.toString(selectSort(arrays)));
System.out.println(Arrays.toString(optSelectSort(arrays1)));
}
}
堆排序
- 思想
- 排序思路:一种树形选择排序方法,(以大根堆为例)第一次循环:将待排序序列构造成一个大根堆,此时,整个序列的最大值就是堆顶的根结点,将其与末尾元素进行交换,然后,末尾就为最大值。第二次循环:将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值,再将其与次尾元素交换。如此反复执行,便能得到一个有序序列了。
- 说明:堆排序每趟产生的有序区一定是全局有序区。
- 实现
public class HeapSort {
public static int[] heapSort(int[] arr){
if (arr == null || arr.length == 0) {
return arr;
}
int length = arr.length;
for (int i = (length>>1)-1; i >= 0; i--) {
adjust(arr, i, length);
}
for (int i = length - 1; i > 0; i--) {
swap(arr, 0, i);
length--;
adjust(arr, 0, length);
}
return arr;
}
protected static void adjust(int []arr,int index,int length){
int left = 2 * index + 1;
int right = 2 * index + 2;
int largestIndex = index;
if (left < length && arr[left] > arr[largestIndex]) {
largestIndex = left;
}
if (right < length && arr[right] > arr[largestIndex]) {
largestIndex = right;
}
if (largestIndex != index) {
swap(arr, index, largestIndex);
adjust(arr, largestIndex, length);
}
}
protected static void swap(int[] arr,int index1,int index2){
int temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
public static void main(String[] args) {
int[] arrays = {8,4,6,1,5,3,9,2,7,0};
System.out.println(Arrays.toString(heapSort(arrays)));
}
}
交换排序
冒泡排序
- 思想
- 通过无序区中相邻元素之间的比较和位置的交换使最大的元素逐渐移动至待排序列的最后。
- 说明:每趟产生的有序区一定是全局有序区。
- 优化:如果在某一次循环中元素位置未进行交换,那么跳出循环。
- 实现
public class BubbleSort {
public static int[] bubbleSort(int[] array){
int temp;
for(int i= 0;i<array.length-1;i++){
for(int j = 0;j < array.length-1-i;j++){
if(array[j] > array[j+1]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
return array;
}
public static int[] optBubbleSort(int[] array){
boolean flag;
int tempPosition = 0;
int len = array.length-1;
int temp;
for(int i= 0;i<array.length-1;i++){
flag = true;
for(int j = 0;j < len;j++){
if(array[j] > array[j+1]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flag = false;
tempPosition = j;
}
}
if (flag){
return array;
}
len = tempPosition;
}
return array;
}
public static void main(String[] args) {
int[] arrays = {8,4,6,1,5,3,9,2,7,0};
int[] arrays1 = {8,4,6,1,5,3,9,2,7,0};
System.out.println(Arrays.toString(bubbleSort(arrays)));
System.out.println(Arrays.toString(optBubbleSort(arrays1)));
}
}
快速排序
- 思想
- 排序思路:冒泡的改进版,采用递归的思想,在待排序的n个元素中任取一个元素(通常取第一个元素)作为基准,把该元素放入适当位置后,数据序列被此元素划分成两部分。所有关键字比改元素关键字小的放在基准的前面,比它大的放在基准的后面,然后基准放在中间位置,这就是一次排序。之后对前后两个部分分别重复上述过程,直至每部分内只有一个元素或没有元素为止。
- 说明:每趟产生的有序区一定是全局有序区,因为每趟都能把一个元素归位。
- 实现
public class QuickSort {
public static int[] RecursionQuickSort(int left,int right,int[] array) {
if(array == null || array.length == 0){
return array;
}
int l, r, base, temp;
if (left > right) {
return array;
}
base = array[left];
l = left;
r = right;
while (l != r) {
while (array[r] >= base && l < r)
r--;
while (array[l] <= base && l < r)
l++;
if (l < r){
temp = array[l];
array[l] = array[r];
array[r] = temp;
}
}
array[left] = array[l];
array[l] = base;
RecursionQuickSort(left,l-1,array);
RecursionQuickSort(l+1,right,array);
return array;
}
public static void main(String[] args) {
int[] arrays = {8,4,6,1,5,3,9,2,7,0};
System.out.println(Arrays.toString(RecursionQuickSort(0,arrays.length-1,arrays)));
}
}
归并排序
- 思想
- 排序思路:将1个长度为n的待排序列划分为n个长度为1的序列,然后进行两两归并,得到n/2个长度为2的有序序列,再进行两两归并,一直到得到一个长度为n的有序序列。
- 说明:每趟产生的有序区只是局部有序区。
- 实现
public class MergeSort {
public static int[] mergeSort(int[] array,int left,int right){
if(left >= right){
return array;
}
int mid = (left + right) / 2;
array = mergeSort(array,left,mid);
array = mergeSort(array,mid+1,right);
merge(array, left, mid, right);
return array;
}
public static void merge(int[] array, int left, int gap, int right){
int[] arr = new int[array.length];
int leftIndex = left;
int rightIndex = gap+1;
int i = 0;
while (leftIndex <= gap && rightIndex <= right){
if(array[leftIndex] < array[rightIndex] ){
arr[i++] = array[leftIndex++];
}else {
arr[i++] = array[rightIndex++];
}
}
while (leftIndex <= gap){
arr[i++] = array[leftIndex++];
}
while (rightIndex <= right){
arr[i++] = array[rightIndex++];
}
for (int j = 0; j < i; j++) {
array[left++] = arr[j];
}
}
public static void main(String[] args) {
int[] arrays = {8,4,6,1,5,3,9,2,7,0};
System.out.println(Arrays.toString(mergeSort(arrays,0,arrays.length-1)));
}
}
基数排序
- 思想
- 基数排序有两种:最低位优先(LSD)和最高位优先(MSD)
- 排序思路:最低位优先的过程是先按最低位的值对元素进行排序,在此基础上再按次低位进行排序,依此类推。由低位向高位,每趟都是根据关键字的一位并在前一趟的基础上对所有元素进行排序,直到最高位。
最高位优先则与此相反 - 说明:基数排序每趟并不产生有序区,只有最后一次排序完成后整个序列才是有序的。
- 实现
public class BaseSort {
public int[] sort(int[] sourceArray) {
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
int maxDigit = getMaxDigit(arr);
return radixSort(arr, maxDigit);
}
private int getMaxDigit(int[] arr) {
int maxValue = getMaxValue(arr);
return getNumLenght(maxValue);
}
private int getMaxValue(int[] arr) {
int maxValue = arr[0];
for (int value : arr) {
if (maxValue < value) {
maxValue = value;
}
}
return maxValue;
}
protected int getNumLenght(long num) {
if (num == 0) {
return 1;
}
int lenght = 0;
for (long temp = num; temp != 0; temp /= 10) {
lenght++;
}
return lenght;
}
private int[] radixSort(int[] arr, int maxDigit) {
int mod = 10;
int dev = 1;
for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
int[][] counter = new int[mod * 2][0];
for (int item : arr) {
int bucket = ((item % mod) / dev) + mod;
counter[bucket] = arrayAppend(counter[bucket], item);
}
int pos = 0;
for (int[] bucket : counter) {
for (int value : bucket) {
arr[pos++] = value;
}
}
}
return arr;
}
private int[] arrayAppend(int[] arr, int value) {
arr = Arrays.copyOf(arr, arr.length + 1);
arr[arr.length - 1] = value;
return arr;
}
public static void main(String[] args) {
int[] arrays = {8,4,6,1,5,3,9,2,7,0};
BaseSort baseSort = new BaseSort();
System.out.println(Arrays.toString(baseSort.sort(arrays)));
}
}