欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

十大排序算法

程序员文章站 2022-06-01 20:20:40
...

以下体会不知大家可曾感同身受:

1、十大排序算法,感觉理解了,却写不下来。

2、一个一个写下来,没什么问题,但是一口气,写完十大排序算法,却困难重重,错误百出。

3、哪怕当时写下来了,过了一段时间却忘了。

今天我之所以要写这篇文章,是因为上述问题,我都曾体会过。而且曾经一度怀疑人生。但是今天我克服上述问题。这不是因为我IQ提高或者记忆力加强的缘故。而是因为我调整学习的策略。在前行的途中,我们中并不乏勇敢者。它们不怕吃苦,奋力拼搏。却仍然无法摆脱平庸。其中原因,除不可抗力因素(资源、天赋等)。而大多人更多是因为方式方法。我想说:“不要轻易怀疑自己,不要轻言放弃。”,下面我谈谈自己学习十大排序算法的心得。

策略

总结主要有一下几点:

1、分清难易、循序渐进、逐步突破。

十大排序算法(冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序)。冒泡排序、选择排序、插入排序可能是相对容易的。但学好这三大排序,对理解更高级排序算法,是大有裨益的。

2、不要把算法孤立起来,尝试分析各个算法之间的区别和联系

我先来抛砖引玉下:

(1) 希尔排序,是在插入排序的基础上,引入了分组的概念。

(2) 快速排序,结合了冒泡排序和归并排序的特点。

(3) 堆排序的算法跟插入排序有点像。

(4) 通排序,小桶排序引入插入排序或者快速排序

(5) 计数排序、基数排序、桶排序是姊妹篇。算法有极高的相似度。

3、各个算法之间的核心特征。

这些可以查看网络对十大排序算法的介绍。

4、反复练习,加深理解。最好能用自己最擅长的理解方式,去解释他。切记不要死记硬背。

代码实现

1、冒泡排序

public void bubbleSort(int[] arr) {
	int i,j;
	for(i = 1; i < arr.length; i++) {
		for(j = 0; j < arr.length - i; j++) {
			if (arr[j] > arr[j+1]) {
				swap(arr, j, j+1);
			}
		}
	}
}

2、选择排序

public void selectSort(int[] arr) {
	int i,j, minIndex;
	for(i = 0; i < arr.length - 1; i++) {
		minIndex = i;
		for(j = i+1; j < arr.length; j++) {
			if (arr[minIndex] > arr[j]) {
				minIndex = j;
			}
		}
		if (minIndex != i) {
			swap(arr, minIndex, i);
		}
	}
}

3、插入排序

public void insertSort(int[] arr) {
	int i,j, insertIndex,tmp;
	for(i = 1; i < arr.length; i++) {
		insertIndex = i;
		tmp = arr[i];
		for (j = i - 1; j >= 0; j--) {
			if (arr[j] > tmp) {
				arr[j+1] = arr[j];
				insertIndex = j;
			}
		}
		if (insertIndex != i) {
			arr[insertIndex] = tmp;
		}
	}
}

4、希尔排序

public void shellSort(int[] arr) {
		
	int gap = 1;
	while(gap < arr.length) {
		gap = gap * 3 + 1;
	}
		
	while(gap > 0) {
		for(int i = gap; i < arr.length; i++) {
			int insertIndex = i;
			int tmp = arr[i];
			for(int j = i - gap; j >= 0; j -= gap) {
				if (arr[j] > tmp) {
					arr[j+gap] = arr[j];
					insertIndex = j;
				}
			}
			if (insertIndex != i) {
				arr[insertIndex] = tmp;
			}
		}
		gap = (int) Math.floor(gap/3);
	}
}

5、归并排序

public class MergeSort {
	public int[] mergeSort(int[] sourceArray) {
		int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
		return sort(arr);
	}
	
	public int[] sort(int[] arr) {
		if (arr.length < 2) {
			return arr;
		}
		int middle = (int) Math.floor(arr.length/2);
		int[] left = Arrays.copyOfRange(arr, 0, middle);
		int[] right = Arrays.copyOfRange(arr, middle, arr.length);
		return merge(sort(left), sort(right));
	}
	
	public int[] merge(int[] left, int[] right) {
		int[] result = new int[left.length + right.length];
		int i = 0;
		while(left.length > 0 && right.length > 0) {
			if (left[0] < right[0]) {
				result[i++] = left[0];
				left = Arrays.copyOfRange(left, 1, left.length);
			} else {
				result[i++] = right[0];
				right = Arrays.copyOfRange(right, 1, right.length);
			}
		}
		
		if (left.length > 0) {
			for(int value:left) {
				result[i++] = value;
			}
		}
		
		if (right.length > 0) {
			for(int value:right) {
				result[i++] = value;
			}
		}
		return result;
	}
}

6、快速排序

package com.ssuqin_kk;

import java.util.Arrays;

public class QuickSort {
	public int[] sort(int[] sourceArray) {
		int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
		quickSort(arr, 0, arr.length - 1);
		return arr;
	}
	
	public void quickSort(int[] arr, int left, int right) {
		if (left < right) {
			int index = partition(arr, left, right);
			quickSort(arr, left, index - 1);
			quickSort(arr, index + 1, right);
		}
	}
	
	public void swap(int[] arr, int a, int b) {
		int tmp = arr[a];
		arr[a] = arr[b];
		arr[b] = tmp;
	}
	
	public int partition(int[] arr, int left, int right) {
		int pivot = left;
		int index = pivot + 1;
		for(int i = index; i <= right; i++) {
			if (arr[i] < arr[pivot]) {
				swap(arr, i, index);
				index++; 
			}
		}
		swap(arr, pivot, index - 1);
		return index - 1;
	}
}

7、堆排序

package com.ssuqin_kk;

import java.util.Arrays;

public class HeapSort {
	public int[] sort(int[] sourceArray) {
		int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
		heapSort(arr);
		return arr;
	}
	
	public void swap(int[] arr, int a, int b) {
		int tmp = arr[a];
		arr[a] = arr[b];
		arr[b] = tmp;
	}
	
	public void heapSort(int[] arr) {
		for(int i = (int) Math.floor(arr.length/2) - 1; i >= 0; i--) {
			adjustHeap(arr, i, arr.length);
		}
		
		for(int j = arr.length - 1; j > 0; j--) {
			swap(arr, 0, j);
			adjustHeap(arr, 0, j);
		}
	}
	
	public void adjustHeap(int[] arr, int i, int length) {
		int tmp = arr[i];
		for(int k = 2*i + 1; k < length; k = 2 * k + 1) {
			if ((k + 1) < length && arr[k+1] > arr[k]) {
				k++;
			}
			
			if (arr[k] > tmp) {
				arr[i] = arr[k];
				i = k;
			} else {
				break;
			}
		}
		
		arr[i] = tmp;
	}
}

8、计数排序

package com.ssuqin_kk;

import java.util.Arrays;

public class CountingSort {
	public int[] sort(int[] sourceArray) {
		int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
		int maxValue = getMaxValue(arr);
		countingSort(arr, maxValue);
		return arr;
	}
	
	public int getMaxValue(int[] arr) {
		int maxValue = arr[0];
		for(int value:arr) {
			if (value > maxValue) {
				maxValue = value;
			}
		}
		return maxValue;
	}
	
	public void countingSort(int[] arr, int maxValue) {
		int[] buckets = new int[maxValue + 1];
		
		for(int i = 0; i < arr.length; i++) {
			buckets[arr[i]]++;
		}
		
		int sortedIndex = 0;
		for(int i = 0; i < buckets.length; i++) {
			while(buckets[i] > 0) {
				arr[sortedIndex++] = i;
				buckets[i]--;
			}
		}
	}
}

9、桶排序

package com.ssuqin_kk;

import java.util.Arrays;

public class BucketSort {
	public int[] sort(int[] sourceArray) {
		int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
		bucketSort(arr, 5);
		return arr;
	}
	
	public int[] arrAppend(int[] arr, int value) {
		arr = Arrays.copyOf(arr, arr.length + 1);
		arr[arr.length - 1] = value;
		return arr;
	}
	
	public void bucketSort(int[] arr, int bucketSize) {
		int minValue = arr[0];
		int maxValue = arr[0];
		
		for(int value:arr) {
			if (value < minValue) {
				minValue = value;
			} else if (value > maxValue) {
				maxValue = value;
			}
		}
		
		int bucketCount = (int) Math.floor((maxValue - minValue)/bucketSize) + 1;
		int[][] buckets = new int[bucketCount][0];
		
		for (int i = 0; i < arr.length; i++) {
			int index = (int) Math.floor((arr[i] - minValue)/bucketSize);
			buckets[index] = arrAppend(buckets[index], arr[i]);
		}
		
		int sortedIndex = 0;
		for(int i = 0; i < bucketCount; i++) {
			if (buckets[i].length <= 0) {
				continue;
			}
			buckets[i] = new QuickSort().sort(buckets[i]);
			for(int value:buckets[i]) {
				arr[sortedIndex++] = value;
			}
		}
	}
}

10、基数排序

package com.ssuqin_kk;

import java.util.Arrays;

public class RadixSort {
	
	public void print(int[] arr) {
		for(int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
		System.out.println();
	}
	
	public int[] radix_sort(int[] sourceArray) {
		int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
		int maxValue = getMaxValue(arr);
		for(int exp = 1; maxValue/exp > 0; exp *= 10) {
			count_sort(arr, exp, arr.length);
		}
		return arr;
	}
	
	public int getMaxValue(int[] arr) {
		int maxValue = arr[0];
		for(int value:arr) {
			if (value > maxValue) {
				maxValue = value;
			}
		}
		return maxValue;
	}
	
	public void count_sort(int[] arr, int exp, int length) {
		int[] output = new int[length];
		int[] buckets = new int[10];
		
		for(int i = 0; i < length; i++) {
			int index = (int) Math.floor(arr[i]/exp%10);
			buckets[index]++;
		}
		
		for(int i = 1; i < buckets.length; i++) {
			buckets[i] += buckets[i-1];
		}
		
		for(int i = arr.length - 1; i >= 0; i--) {
			int index = (int) Math.floor(arr[i]/exp%10);
			output[buckets[index] - 1] = arr[i];
			buckets[index]--;
		}
		
		for(int i = 0; i < arr.length; i++) {
			arr[i] = output[i];
		}
		
		print(arr);
	}
}