java的七种常用排序算法

1、冒泡排序(每一躺选出一个最大或者最小放在最后)

import java.util.Arrays;

/**
 * 
 * <p>Title: a1BubbleSort</p>  
 * <p>Description: 稳定的排序算法 </p>  
 * @author Shenxinyuan
 * @date 2020年9月11日
 */
public class a1BubbleSort {
    
    

	public static void main(String[] args) {
    
    
		// System.out.println("你好,java!");

		int[] arr = {
    
     4, 8, 9, 5, 7, 0, -1 };
		BubbleSort(arr);
		System.out.println(Arrays.toString(arr));
	}

	/**
	 * 
	 * <p>Title: BubbleSort</p>  
	 * <p>Description: 空间复杂度(O(1))   时间复杂度(O(n^2))</p>  
	 * @param arr
	 */
	public static void BubbleSort(int[] arr) {
    
    
		if (arr == null || arr.length == 0) {
    
    
			return;
		}
		//优化,置一个变量判断是否发生交换,每一趟都少遍历比较一个数
		boolean label = true;
		for (int i = 0; i < arr.length && label; i++) {
    
    
			label = false;
			for (int j = 0; j < arr.length - 1 - i; j++) {
    
    
				if (arr[j + 1] < arr[j]) {
    
    
					int temp = arr[j + 1];
					arr[j + 1] = arr[j];
					arr[j] = temp;
					label = true;
				}
			}
		}
	}
}

2、简单选择排序及其优化

思想:每一躺找出最大或者最小的元素的下标跟对应位置交换
优化思想:每一躺找出最大和最小的元素的下标跟对应位置交换

import java.util.Arrays;

public class a2SelectSort {
    
    
	public static void main(String[] args) {
    
    
		int[] arr = {
    
     4, 8, 9, 5, 7, 0, -1 };
		//SelectSort(arr);
		optimizedSelectSort(arr);
		System.out.println(Arrays.toString(arr));
	}
		
	//不稳定的排序算法,举个例子,序列5 8 5 2 9, 我们知道第一遍选择第1个元素5会和2交换,
    // 那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法
	private static void SelectSort(int[] arr) {
    
    
		// TODO Auto-generated method stub
		if(arr==null || arr.length==0) {
    
    
			return;
		}
		//时间复杂度(O(n^2))   空间复杂度(O(1))
	    //从待排序列选择最大或最小数据跟第一个交换
		for(int i =0;i<arr.length;i++) {
    
    
			int minIndex = i;
			for(int j =i+1;j<arr.length;j++) {
    
    
				//升序
				if(arr[j]<arr[minIndex]) {
    
    
					minIndex = j;
				}
			}
			if(minIndex != i) {
    
    
				swap(i, minIndex, arr);
			}
		}
		
	}
	
	//从待排序列中选择最大值和最小值选择排列
    //时间复杂度(O(n/2)) 空间复杂度(O(1))
	private static void optimizedSelectSort(int[] arr) {
    
    
		if(arr == null|| arr.length == 0) {
    
    
			return;
		}
		
		for(int i=0;i<=(arr.length>>1);i++) {
    
    
			int minIndex = i;
			int maxIndex = i;
			for(int j =i+1;j<=arr.length-1-i;j++) {
    
    
				if(arr[j]<arr[minIndex]) {
    
    
					minIndex = j;
					continue;
				}
				if(arr[j]>arr[maxIndex]) {
    
    
					maxIndex = j;
				}
			}
			if(minIndex != i) {
    
    
				swap(i, minIndex, arr);
			}
			if(maxIndex != i) {
    
    
				swap(arr.length-1-i, maxIndex, arr);
			}
		}
	}

	private static void swap(int i, int j, int[] arr) {
    
    
		int temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}
}

3、插入排序

思想:在有序序列中找第一个比无需序列中第一个元素大的元素的下标,然后将该下标的元素放到有序序列的对应元素的前边
优化思想:在有序列中找第一个比无序序列中第一个元素小的元素的下标,然后将该下标的元素放到有序序列对应元素的后边。

import java.util.Arrays;

public class a3InsertSort {
    
    
	public static void main(String[] args) {
    
    
		int[] arr = {
    
     4, 8, 9, 5, 7, 0, -1 };
		//InsertSort(arr);
		optimizedInsertSort(arr);
		System.out.println(Arrays.toString(arr));
	}

	private static void InsertSort(int[] arr) {
    
    
		// TODO Auto-generated method stub
		if(arr == null||arr.length==0) {
    
    
			return;
		}
		
		for(int i =0;i<arr.length;i++) {
    
    
			int j;
			//在前i个升序数据,找到比第i个数据大的数,跳出循环开始交换数据
			for(j =0;j<i;j++) {
    
    
				if(arr[j] > arr[i]) {
    
    
					break;
				}
			}
			
			//以交换的形式,挪动数据arr[i]到有序数据的第j位
			for(int k = i-1;k>= j;k--) {
    
    
				swap(k+1, k, arr);
			}
		}
	}
	
	private static void optimizedInsertSort(int[] arr) {
    
    
		// TODO Auto-generated method stub
		if(arr == null||arr.length==0) {
    
    
			return;
		}else {
    
    
			for(int i= 0;i<arr.length;i++) {
    
    
				int j;
				int temp = arr[i];//把第i个数据保存在temp中,方便交换数据
				//升序
				for(j = i-1;j>=0;j--) {
    
    
					//在前i个有序数据中招第一个比第i个小的数,交换
					if(arr[j] < temp) {
    
    
						break;
					}else {
    
    
						//移动数据ing
						arr[j+1] = arr[j];
					}
				}
				//找到该位置,把temp给arr[j+1]
				arr[j+1] = temp;
			}
		}
	}
	
	private static void swap(int i, int j, int[] arr) {
    
    
		int temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}
}

4、希尔排序(优化插入排序的拓展)

import java.util.Arrays;

public class a3ShellSort {
    
    

	public static void main(String[] args) {
    
    
		int[] arr = {
    
    10, 8, 1, 0, 19,
                2, 4, 28, 30, 56,
                24, 9, 5, 15, 12,
                11, 44, 77};
        shellSortSort(arr, 3);
        //System.out.println(Arrays.toString(arr));
        for(int demo:arr) {
    
    
        	
        	System.out.print(demo+" ");
        }
	}

	private static void shellSortSort(int[] arr, int gap) {
    
    
		// TODO Auto-generated method stub
		while(gap >= 1) {
    
    //直到间距为1
			for(int i =0;i<arr.length;i++) {
    
    
				int j =0;
				int temp = arr[i];
				for(j = i-gap;j>=0;j-=gap) {
    
    
					if(arr[j] <= temp) {
    
    
						break;
					}else {
    
    
						arr[j+gap] = arr[j];
					}
				}
				arr[j+gap] = temp;
			}
			gap--;
		}
	
	}

	
}

5、快速选择排序

import java.util.Arrays;
import java.util.Stack;

public class a4QuickSort {
    
    
	public static void main(String[] args) {
    
    
		int[] arr = {
    
    10, 2, 19, 0, 8, 100, 28, 7, 1, 15,7};
		quickSort(arr);
		//quickSortByWhile(arr);
		System.out.println(Arrays.toString(arr));
	}

	private static void quickSort(int[] arr) {
    
    
		// TODO Auto-generated method stub
		if (arr.length == 0 || arr == null) {
    
    
            return ;
        } else {
    
    
            quick(arr,0,arr.length-1);
        }
	}

	private static void quick(int[] arr, int low, int high) {
    
    
		// TODO Auto-generated method stub
		
		int partition = partition(low,high,arr);
        //partition左边的数据都比它小,右边的数据都比他大
        //判断左边的数据大于1 个
        if(partition > low +1){
    
    
            quick(arr, low,partition-1);
        }
        //判断右边的数据大于1 个
        if(partition < high-1){
    
    
            quick(arr, partition+1,high);
        }
	}

	private static int partition(int low, int high, int[] arr) {
    
    
		// TODO Auto-generated method stub
		int mark = arr[low];
        while (low < high) {
    
    
            //从后往前找比基准数据小的元素
            while (arr[high] >= mark && low < high) {
    
    
                high--;     //high可能会越界
            }
            if (low == high) {
    
    
                break;
            }
            if(arr[high]<mark){
    
    
                arr[low] = arr[high];
            }
            //从后往前找比基准数据小的元素
            while (arr[low] <= mark && low < high) {
    
    
                low++;
            }
            if (low == high) {
    
    
                break;
            }
            if(arr[low]>mark) {
    
    
                arr[high] = arr[low];
            }
        }
        arr[low] = mark;
		return low;
	}

	private static void quickSortByWhile(int[] arr) {
    
    
		// TODO Auto-generated method stub
		//参数合法性判断
        if(arr == null||arr.length==0){
    
    
            return;
        }
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        stack.push(arr.length-1);
        while(!stack.isEmpty()){
    
    
            int high = stack.pop();
            int low = stack.pop();
            //mark左边的数字都比他小,右边的数值都比他大
            int mid = partition(low,high,arr);
            //保证partition后的徐磊长度大于一
            //判断左边序列的个数是否大于一
            if(mid > low+1){
    
    
                stack.push(low);
                stack.push(mid-1);
            }
            //判断右边序列的个数是否大于一
            if(mid < high-1){
    
    
                stack.push(mid+1);
                stack.push(high);
            }
        }
	}
}

6、堆排序

import java.util.Arrays;

public class a5HeapSort {
    
    
	public static void main(String[] args) {
    
    
		int[] arr = {
    
    16, 7, 3, 20, 17, 8};
        heapSort(arr);
        for (int i : arr) {
    
    
            System.out.print(i + " ");
        }
        System.out.println();
        System.out.println(Arrays.toString(arr));
	}

	private static void heapSort(int[] arr) {
    
    
		// TODO Auto-generated method stub
		//创建堆,大根
        for (int i = (arr.length - 1) / 2; i >= 0; i--) {
    
    
            //从第一个非叶子结点从下至上,从右至左调整结构
            adjustHeap(arr, i, arr.length);
        }
        //调整堆结构+交换堆顶元素与末尾元素
        for (int i = arr.length - 1; i > 0; i--) {
    
    
            //将堆顶元素与末尾元素进行交换
            int temp = arr[i];
            arr[i] = arr[0];
            arr[0] = temp;
            //重新对堆进行调整
            adjustHeap(arr, 0, i);
        }
	}

	private static void adjustHeap(int[] arr, int parent, int length) {
    
    
		// TODO Auto-generated method stub
		//将temp作为父节点
        int temp = arr[parent];
        //左孩子
        int lChild = 2 * parent + 1;
        while (lChild < length) {
    
    
            //右孩子
            int rChild = lChild + 1;
            // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点
            if (rChild < length && arr[lChild] < arr[rChild]) {
    
    
                lChild++;
            }
            // 如果父结点的值已经大于孩子结点的值,则直接结束
            if (temp >= arr[lChild]) {
    
    
                break;
            }
            // 把孩子结点的值赋给父结点
            arr[parent] = arr[lChild];
            //选取孩子结点的左孩子结点,继续向下筛选
            parent = lChild;
            lChild = 2 * lChild + 1;
        }
        arr[parent] = temp;
	}
}

7、归并排序


public class a6MergeSort {
    
    

	public static void main(String[] args) {
    
    
		int[] a = {
    
    49, 38, 65, 97, 76, 13, 27, 50};
        mergeSort(a, 0, a.length - 1);
        System.out.println("排好序的数组:");
        for (int e : a)
            System.out.print(e + " ");
	}

	private static void mergeSort(int[] a, int start, int end) {
    
    
		// TODO Auto-generated method stub
		if (start < end) {
    
    //当子序列中只有一个元素时结束递归
            int mid = (start + end) / 2;//划分子序列
            mergeSort(a, start, mid);//对左侧子序列进行递归排序
            mergeSort(a, mid + 1, end);//对右侧子序列进行递归排序
            merge(a, start, mid, end);//合并
        }
	}

	//空间复杂度度较大O(n)
	//时间复杂度:nlog2n
	private static void merge(int[] a, int left, int mid, int right) {
    
    
		// TODO Auto-generated method stub
		int[] tmp = new int[a.length];//辅助数组
        int p1 = left, p2 = mid + 1, k = left;//p1、p2是检测指针,k是存放指针

        while (p1 <= mid && p2 <= right) {
    
    
            if (a[p1] <= a[p2])
                tmp[k++] = a[p1++];
            else
                tmp[k++] = a[p2++];
        }

        //把剩余元素放入temp临时数组
        while (p1 <= mid) tmp[k++] = a[p1++];//如果第一个序列未检测完,直接将后面所有元素加到合并的序列中
        while (p2 <= right) tmp[k++] = a[p2++];//同上

        //复制回原素组
        for (int i = left; i <= right; i++)
            a[i] = tmp[i];
	}
}

猜你喜欢

转载自blog.csdn.net/sxy3180911/article/details/107718922