目录
常见排列列表
算法程序编写原则
对数器——验证算法
可以通过以下代码实现对数器来验证各个排序算法的正确与否
import java.util.Arrays;
import java.util.Random;
public class DataChecker {
static int[] generateRandomArray(){
Random r = new Random();
int[] arr = new int[10000];
for (int i = 0; i < arr.length; i++){
arr[i] = r.nextInt(10000);
}
return arr;
}
static void check(){
boolean same = true;
for (int times=0; times<1000; times++){
int[] arr = generateRandomArray();
int[] arr2 = new int[arr.length];
System.arraycopy(arr, 0, arr2, 0, arr.length);
Arrays.sort(arr);
Selection.sort(arr2);
Bubble.sort(arr2);
Insertion.sort(arr2);
Shell.sort(arr2);
Merge.sort(arr2,0,arr2.length-1);
Quick.sort(arr2,0,arr.length-1);
for (int i = 0; i < arr2.length; i++){
if (arr[i] != arr2[i]) same = false;
}
}
System.out.println(same == true ? "right" : "wrong");
}
public static void main(String[] args){
check();
}
}
1.选择排序
public class Selection {
public static void main(String[] args){
int[] arr = {5, 3, 6, 8, 1, 7, 9, 4, 2};
sort(arr);
print(arr);
}
static void sort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++){
int minPos = i;
for (int j = i + 1; j < arr.length; j++){
minPos = arr[j] < arr[minPos] ? j : minPos;
}
swap(i,minPos,arr);
}
}
static void swap(int i,int j,int[] arr){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
static void print(int[] arr){
for (int i = 0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}
2.冒泡排序
public class Bubble {
public static void main(String[] args){
int[] a = {9, 3, 1, 4, 6, 8, 7, 5, 2};
sort(a);
print(a);
}
static void sort(int[] arr){
for (int i=arr.length-1; i>0; i--)
findMax(arr,i);
}
static void findMax(int[] arr,int i){
for (int j=0; j<i; j++)
if (arr[j] > arr[j+1]) swap(arr, j, j+1);
}
static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
static void print(int[] arr){
for (int i=0; i<arr.length; i++)
System.out.print(arr[i] + " ");
}
}
3.插入排序
public class Insertion {
public static void main(String[] args){
int[] arr = {9, 3, 1, 4, 6, 8, 7, 5, 2};
sort(arr);
print(arr);
}
static void sort(int[] arr){
for (int i=1; i<arr.length; i++)
for (int j=i; j>0 && arr[j-1]>arr[j]; j--)
swap(arr, j, j-1);
}
static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
static void print(int[] arr) {
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
}
}
4.希尔排序
public class Shell {
public static void main(String[] args){
int[] arr = {9, 6, 11, 3, 5, 12, 8, 7, 10, 15, 14, 4, 1, 13, 2};
sort(arr);
print(arr);
}
static void sort(int[] arr){
int h = 1;
while (h <= arr.length/3 ){
h = h*3 + 1;
}
for (int gap = h; gap>0; gap = (gap-1)/3 )
for (int i=gap; i<arr.length; i+=gap)
for (int j=i; j>0; j-=gap)
if (arr[j] < arr[j-gap]) swap(arr,j,j-gap);
}
static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
static void print(int[] arr){
for (int i=0; i<arr.length; i++)
System.out.print(arr[i] + " ");
}
}
5.归并排序
public class Merge {
public static void main(String[] args){
int[] arr = {1, 4, 7, 8, 3, 6, 9};
sort(arr,0,arr.length-1);
print(arr);
}
public static void sort(int[] arr, int left, int right){
if (left == right) return;
int mid = left + (right - left)/ 2;
//左边排序
sort(arr, left, mid);
//右边排序
sort(arr,mid+1, right);
merge(arr, left, mid+1, right);
}
static void merge(int[] arr, int leftPtr, int rightPtr, int rightBound){
int mid = rightPtr - 1;
int[] temp = new int[rightBound - leftPtr + 1];
int i = leftPtr;
int j = rightPtr;
int k = 0;
while (i <= mid && j <= rightBound)
temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
while (i <= mid)
temp[k++] = arr[i++];
while (j <= rightBound)
temp[k++] = arr[j++];
for (int m = 0; m<temp.length; m++)
arr[leftPtr + m] = temp[m];
}
static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
static void print(int[] arr){
for (int i=0; i<arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}
6.快速排序
public class Quick {
public static void main(String[] args){
int[] arr = {1, 4, 6, 9, 10, 2, 3, 5, 8, 7};
sort(arr,0,arr.length-1);
print(arr);
}
public static void sort(int[] arr, int leftBound, int rightBound){
if (leftBound >= rightBound) return;
int mid = partition(arr,leftBound,rightBound);
sort(arr,leftBound,mid-1);
sort(arr,mid+1,rightBound);
}
static int partition(int[] arr, int leftBound, int rightBound){
int piovt = arr[rightBound];
int left = leftBound;
int right = rightBound -1;
while (left <= right) {
while (left <= right && arr[left] <= piovt) left++;
while (left <= right && arr[right] > piovt) right--;
if (left < right) swap(arr, left, right);
}
swap(arr,left,rightBound);
return left;
}
static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
static void print(int[] arr){
for (int i=0; i<arr.length; i++)
System.out.print(arr[i] + " ");
}
}
双轴快排(Dual Pivot Quicksort)
Array.sort流程图:
- TimSort
- 双插入排序(pair insertion sort)
- 荷兰国旗问题 (Dutch National Flag)
7.计数排序
import java.util.Arrays;
public class Count {
public static void main(String[] args){
int[] arr = {2, 4, 2, 3, 7, 1, 1, 0, 0, 5, 6, 9, 8, 5, 7, 4, 0, 9};
int[] result = sort(arr);
System.out.print(Arrays.toString(result));
}
public static int[] sort(int[] arr){
int[] result = new int[arr.length];
int[] count = new int[10];
for (int i=0; i<arr.length; i++)
count[arr[i]]++;
System.out.println(Arrays.toString(count));
for (int i=1; i<count.length;i++)
count[i] = count[i] + count[i-1];
System.out.println(Arrays.toString(count));
for (int i=arr.length-1; i>=0; i--)
result[--count[arr[i]]] = arr[i];
return result;
}
}
验证测试类:
import com.gemini.sort.Count;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Random;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CountSortTest {
int[] generateRandomArray(){
Random r = new Random();
int[] arr = new int[10000];
for (int i=0; i<arr.length; i++){
arr[i] = r.nextInt(10);
}
return arr;
}
@Test
void testSort(){
int[] a = generateRandomArray();
int[] result = Count.sort(a);
Arrays.sort(a);
boolean same = true;
for (int i=0; i<a.length; i++){
if (result[i] != a[i]) same = false;
}
assertEquals(true,same);
}
}
8.基数排序
import java.util.Arrays;
public class Radix {
public static void main(String[] args) {
int[] arr = {421,240,115,532,305,430,124};
int maxPos = findMaxPosition(arr);
sort(arr,maxPos);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr,int maxPos) {
int[] result = new int[arr.length];
int[] count = new int[10];
for (int i=0; i<maxPos; i++){
int division = (int)Math.pow(10,i);
System.out.println(division);
for (int j=0; j<arr.length; j++){
count[arr[j] / division % 10]++;
}
System.out.println(Arrays.toString(count));
for (int m=1; m<count.length; m++){
count[m] = count[m] + count[m-1];
}
System.out.println(Arrays.toString(count));
for (int n=arr.length-1; n>=0; n--){
int num = arr[n]/division % 10;
result[--count[num]] = arr[n];
}
//将result数组内容复制到arr数组
System.arraycopy(result, 0, arr, 0, arr.length);
//将count数组去全部置零
Arrays.fill(count, 0);
}
}
static int findMaxPosition(int[] arr) {
int Max = 0;
int MaxPos = 0;
for (int i=0; i<arr.length-1; i++){
Max = Math.max(arr[i], arr[i + 1]);
}
while (Max != 0 ){
Max = Max / 10;
MaxPos++;
}
return MaxPos;
}
}
9.桶排序