常见的排序列表
选择排序
- 指定第一个位置为最小值;
- 从其余值中选择最小值与指定的最小位置比较,如果其余值中选择的最小值较小,进行值交换
public class SelectionSort {
public static void main(String[] args){
int arr[] = {7,4,1,5,8,6,2,3,9};
print(arr);
for(int i=0; i<arr.length; i++) {
int minPos = i;
for (int j = i+1; j < arr.length; j++) {
minPos = arr[j] < arr[minPos] ? j : minPos;
}
System.out.println("minPos:" + minPos);
swap(arr, i,minPos);
System.out.println("经过第" + i +"次循环后,数组的内容:");
print(arr);
}
}
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] + " ");
}
}
}
冒泡排序
for(int i=arr.length-1; i>0; i--){
for(int j=0;j<i;j++){
if(arr[j]>arr[j+1]) swap(arr,j,j+1);
}
}
完整代码:
public class BubbleSort {
public static void main(String args[]){
int arr[] = {7,5,2,1,4,6,3,9,8};
Bubble(arr);
print(arr);
}
static void Bubble(int[] arr) {
for(int i=arr.length-1; i>0; 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 j, int i) {
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
static void print(int[] arr) {
for(int k=0;k<arr.length;k++){
System.out.print(arr[k]+" ");
}
}
}
考虑到时间复杂度最佳情况下(序列原本就是正序),进一步改进使得时间复杂度是O(n)。完善后的代码是:
static void BestBubble(int[] arr) {
boolean didSwap;
for(int i=arr.length-1; i>0; i--){
didSwap = false;
for(int j=0;j<i;j++){
if(arr[j]>arr[j+1]) {
swap(arr, j, j + 1);
didSwap = true;
}
}
if(didSwap == false)
return;
}
}
希尔排序
public class ShellSort {
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 = 3*h+1;
}
//gap使用Knuth序列
for(int gap = h; gap>0; gap=(gap-1)/3){ //还有一种比Knuth序列效率低一些的,是gap /=2
//下面是插入排序的代码改编过来的
for(int i=gap;i<arr.length;i++){
for(int j=i;j>gap-1;j-=gap){
if(arr[j-gap]>=arr[j])
swap(arr,j,j-gap);
}
}
}
}
static void print(int[] arr) {
for(int k=0; k<arr.length;k++){
System.out.print(arr[k] + " ");
}
}
static void swap(int arr[], int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
归并排序
public class MergeSort {
public static void main(String args[]){
int arr[] = {1,4,7,8,3,6,9};
merge(arr);
}
static void print(int[] arr) {
for (int k =0;k<arr.length;k++){
System.out.print(arr[k] + " ");
}
}
static void merge(int[] arr) {
int mid = arr.length/2;
int temp[] = new int[arr.length];
int i = 0;
int j = mid + 1;
int k = 0;
while(i <= mid && j < arr.length){
if(arr[i] <= arr[j]){
temp[k++] = arr[i++];
}else{
temp[k++] = arr[j++];
}
}
while(i<=mid) temp[k++] = arr[i++];
while (j<arr.length) temp[k++] = arr[j++];
print(temp);
}
}
快速排序
public class QuickSort {
public static void main(String args[]){
int arr[] = {7,3,2,8,1,9,5,4,6};
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 pivot = arr[rightBound];
int left = leftBound;
int right = rightBound - 1;
while(left <= right){
while (left <= right && arr[left]<=pivot) left++;
while (left <= right && arr[right]>pivot) 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 k=0;k<arr.length;k++){
System.out.print(arr[k] + " ");
}
}
}
计数排序
import java.util.Arrays;
public class CountSort {
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.println(Arrays.toString(result));
}
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=0,j=0;i<count.length;i++){
while(count[i]-- > 0) result[j++] = i;
}
return result;
}
}
基数排序
原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。
import java.util.Arrays;
public class RadixSort {
public static void main(String[] args){
int[] arr = {421,240,115,532,305,430,124};
int[] result = sort(arr);
System.out.println((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<3;i++){
int division =(int)Math.pow(10,i);
System.out.println(division);
for(int j=0; j<arr.length; j++){
int num = arr[j]/division % 10;
System.out.println(num + " ");
count[num]++;
}
System.out.println();
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];
}
System.arraycopy(result,0,arr,0,arr.length);
Arrays.fill(count,0);
}
return result;
}
static void findMax(int[] a, int n){
for(int j=0;j<n;j++){
if(a[j] > a[j+1]) swap(a,j,j+1);
}
}
static void swap(int[] a,int i,int j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}