常用的八种排序算法总结

1.冒泡排序

最简单的一种

public class bubSort {
    public static void main(String[] args) {
        int arr[] = {6,8,5,2,4,5,7};
        for(int i = 0;i < arr.length - 1;i++){
            for(int j = 0;j < arr.length - 1 - i;j++){
                if(arr[j] > arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j+1] = temp;
                }
            }
        }
        for(int i = 0;i < arr.length;i++){
            System.out.print(arr[i] + "\t");
        }
    }
}

2.选择排序

这个和冒泡,插入排序有点类似

/*
 * 选择排序:每次选择数组中最大(或最小)的值放在数组的尾部(首部)
 */
public class selectSort {

    public static void main(String[] args) {
        int[] arr = {6,8,2,5,7,4};
        fun(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void fun(int[] arr){
        if(arr == null || arr.length == 0){
            return;
        }
        for(int i = 0;i < arr.length;i++){
            int index = i;
            for(int j = i + 1;j < arr.length;j++){
                if(arr[j] < arr[index]){
                    index = j;
                }
            }
            int temp=arr[i];
            arr[i]=arr[index];
            arr[index]=temp;
        }
    }
}

3.插入排序

/*
* 插入排序,取出第i+1个元素,与前面的元素一一比较,小的排在前
 */
public class insertSort {

    public static void main(String[] args) {
        int[] arr = {6,8,2,5,7,4};
        inSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void inSort(int[] arr){
        for(int i = 1;i < arr.length;i++){
            for(int j = i;j > 0;j--){
                if(arr[j] < arr[j - 1]){
                    int temp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
    }
}
或者:
public void test3() {
	int i,j,temp;
	for(i=1;i<array.length;i++) {
		temp=array[i];
		for(j=i-1;j>=0;j--) {
			if(temp>array[j]) {
				break;
			}else {
				array[j+1]=array[j];
			}
		}
		array[j+1]=temp;
	}
	System.out.println(Arrays.toString(array));
}

4.归并排序

public class mergeSort {

    //两路归并算法,两个排好序的子序列合并为一个子序列
    public static void merge(int []a,int left,int mid,int right){
        int p1,p2,index;
        p1 = left;
        index = left;
        p2 = mid + 1;
        int temp[] = new int[a.length];
        while(p1 <= mid && p2 <= right){
            if(a[p1] <= a[p2]){
                temp[index++] = a[p1++];
            }else{
                temp[index++] = a[p2++];
            }
        }
        while(p1 <= mid){
            temp[index++] = a[p1++];
        }
        while(p2 <= right){
            temp[index++] = a[p2++];
        }
        for (int i = left; i <=right; i++){
            a[i]=temp[i];
        }
    }

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

    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+" ");
    }
}

5.快速排序

/*
* 既不浪费空间又可以快一点的排序算法
 * 从两端开始
 */
public class quickSort {
    public static void main(String[] args) {
        int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
        quickSortCore(arr,0,arr.length - 1);
        for(int num : arr){
            System.out.print(num + "\t");
        }
    }

    public static void quickSortCore(int[] arr,int left,int right){
        int i,j,stand,temp;
        if(left > right){
            return;
        }
        stand = arr[left];
        i = left;
        j = right;
        while (i != j){
            while(i < j && stand <= arr[j]){
                j--;
            }
            while(i < j && stand >= arr[i]){
                i++;
            }
            if(i < j){//注意这个坑,防止与下面的值交换重复
                temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        arr[left] = arr[i];
        arr[i] = stand;
        quickSortCore(arr,left,j - 1);
        quickSortCore(arr,j + 1,right);
    }
}

6.希尔排序

public class shellSort {

    public static void main(String[] args) {
        int[] arr = {1, 1, 7, 3, 5, 6, 9, 4};
        fun1(arr);

        for (int i : arr) {
            System.out.print(i + "\t");
        }
    }


    //第一种方法
    public static void fun1(int[] data){
        int j = 0;
        int temp = 0;
        for (int increment = data.length / 2; increment > 0; increment /= 2) {
            for (int i = increment; i < data.length; i++) {
                temp = data[i];
                for (j = i - increment; j >= 0; j -= increment) {
                    if (temp < data[j]) {
                        data[j + increment] = data[j];
                    } else {
                        break;
                    }
                }
                data[j + increment] = temp;
            }
        }
    }

    //第二种方法
    public static void fun2(int[] arr){
        for(int step = arr.length / 2;step > 0;step /= 2){
            for(int i = step;i < arr.length;i++){
                int value = arr[i];
                int j;
                //对步长区间中具体的元素进行比较
                for (j = i - step; j >= 0 && arr[j] > value; j -= step) {
                    //j为左区间的取值,j+step为右区间与左区间的对应值。
                    arr[j + step] = arr[j];
                }
                System.out.println(j+"...." + (j+step));
                //此时step为一个负数,[j + step]为左区间上的初始交换值
                arr[j + step] = value;
            }
        }
    }
}

7.堆排序

堆排序比较复杂推荐去看B站的视频点击跳转
/*
 * 对于堆中的第i个元素,其父元素:(i-1)/2,左子节点:2i+1,右子节点:2i+2
 */
public class heapSort {

    /**
     * 交换节点值
     * @param tree 传入的树
     * @param i 较大的值
     * @param j 较小的值
     */
    public static void swap(int[] tree,int i,int j){
        int temp = tree[i];
        tree[i] = tree[j];
        tree[j] = temp;
    }

    /**
     *
     * @param tree 传入的树
     * @param n 树的节点个数
     * @param i 某个节点
     */
    public static void heapExchange(int[] tree,int n,int i){
        if(i >= n){
            return;
        }
        int c1 = 2*i + 1;
        int c2 = 2*i + 2;
        int max = i;
        if(c1 < n && tree[c1] > tree[max]){
            max = c1;
        }
        if(c2 < n && tree[c2] > tree[max]){
            max = c2;
        }
        if(max != i){
            swap(tree,max,i);
            //为了保证是最大顶堆,交换值后还要和其子节点继续判断
            heapExchange(tree,n,max);
        }
    }


    /**
     * 对于一棵深度为n的树,从n-1层开始倒序创建最大顶堆
     */
    public static void build_heapTree(int[] tree,int n){
        int lastNode = n - 1;//找到最后一个节点,通过它找到它的父节点
        int parent = (lastNode - 1) / 2;
        for(int i = parent;i >= 0;i--){
            heapExchange(tree,n,i);
        }
    }

    /**
     * 根据创建好的最大顶堆完成排序
     * 思路:对于排好的最大顶堆,把堆顶的元素和最后一个交换,最后一个就是最大的数了,再切去
     *      交换后的已经不是最大顶堆了,需要再排序一下,
     */
    public static void heapSortCore(int[] tree,int n){
        build_heapTree(tree,n);//创建最大顶堆
        for(int i = n - 1;i >= 0;i--){
            swap(tree,i,0);//注意这里的切去,根据i就是切去后的结果了
            heapExchange(tree,i,0);//从堆顶开始
        }
    }

    public static void main(String[] args) {
        int[] tree = {2,5,3,1,10,4};
        int n = 6;
        heapSortCore(tree,n);
        System.out.println(Arrays.toString(tree));
    }
}

8.基数排序

public class numSort {
    public static void main(String[] args) {
        int[] arr = {23,6,189,45,9,287,56,1,798,34,65,652,5};
        sort(arr);
        System.out.println(Arrays.toString(arr));

    }

    public static void sort(int[] arr){
        int maxNum = Integer.MIN_VALUE;//存放数组中最大的数字
        int[][] arrTemp = new int[10][arr.length];//存放临时数据的数组,有十个,每个可以存放的最大长度为arr长度
        int[] counts = new int[10];//用作指针,10个长度对应0~10中每个数字出现的次数,例如counts[2++]对应arrTemp中存放2的位置,从0开始,依次递加
        for(int i = 0;i < arr.length;i++){//找到最大的数字
            if(arr[i] > maxNum){
                maxNum = arr[i];
            }
        }
        int length = (maxNum+"").length();//求最大数字的长度
        for(int i = 0,n = 1;i < length;i++,n *= 10){//根据长度计算比较次数,n是中间变量,用来取余
            for(int j = 0;j < arr.length;j++){
                int num = arr[j]/n%10;//除就是截取n的位数后面的数,取模就是取最后一位
                arrTemp[num][counts[num]] = arr[j];
                counts[num]++;
            }
            int index = 0;
            //把存入的数据拿出来
            for(int k= 0;k < counts.length;k++){
                if(counts[k] != 0){//代表有数字
                    //循环取出元素
                    for(int m = 0;m < counts[k];m++){
                        arr[index] = arrTemp[k][m];
                        index++;
                    }
                    //数据拿出来以后置零方便下一次循环用
                    counts[k] = 0;
                }
            }
        }
    }
}

发布了37 篇原创文章 · 获赞 11 · 访问量 3877

猜你喜欢

转载自blog.csdn.net/Alphr/article/details/105083253
今日推荐