0
点赞
收藏
分享

微信扫一扫

排序算法列表

探头的新芽 2022-02-19 阅读 88
package com.algorithm.exersice;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 查找和排序:
 * 查找:顺序查找O(n)、二分查找O(lgn)、哈希表查找O(1)、二叉排序树查找O(lgn)
 * 排序:插入排序、冒泡排序、归并排序、快速排序
 */
public class SearchAndSort {

    public static void main(String[] args) {
        int a[] = {39,5,3,16,27,2,19,38,50,4,47,15,48};
        //int a[] = {1,2,3,4,5};
        //bubbleSort(a); // 冒泡排序
        //selectionSort(a); // 选择排序
        //insertionSort(a); //插入排序
        //shellSort(a); // 希尔排序
        //mergeSort(a); // 归并排序
        print(a);
    }

    /**
     * 归并排序
     * T(n) = 2T(n/2)+n
     * 时间复杂度:平均O(nlgn),最坏O(nlgn),最好O(nlgn)
     * 空间复杂度O(n)
     * 稳定排序
     * 时间复杂度固定,不受输入数据影响,表现优于选择排序
     * 缺点:需要额外空间
     * @param a
     */
    private static void mergeSort(int[] a) {
        if (a == null || a.length == 0 || a.length == 1) {
            return;
        }
        int temp[] = Arrays.copyOf(a,a.length);

        //mergeSortRecursively(a, 0, a.length-1, temp); //递归算法
        mergeSortNonRecursively(a, temp); //非递归算法
    }

    /**
     * 归并排序非递归算法
     */
    private static void mergeSortNonRecursively(int[] a, int[] temp) {
        int gap=0, start=0, current=0, i=0, j=0;
        for (gap=1; gap<a.length; gap*=2) {
            for (start=0; start<a.length; start=start+gap*2) {
                i=start;
                j=start+gap;
                current=start;
                while (i<start+gap && i<a.length && j<start+gap*2 && j<a.length) {
                    if (a[i]<=a[j]) {
                        temp[current++] = a[i++];
                    } else {
                        temp[current++] = a[j++];
                    }
                }
                while (i<start+gap && i<a.length) {
                    temp[current++] = a[i++];
                }
                while (j<start+gap*2 && j<a.length) {
                    temp[current++] = a[j++];
                }
            }
            for (i=0; i<a.length; i++) {
                a[i] = temp[i];
            }

        }
    }

    /**
     * 归并排序递归算法
     */
    private static void mergeSortRecursively(int[] a, int start, int end, int temp[]) {
        if (start >= end) {
            return;
        }
        int rightStart = start+(end-start)/2+1;
        mergeSortRecursively(a,start, rightStart-1, temp);
        mergeSortRecursively(a,rightStart, end, temp);
        int i=start, j=rightStart;
        int currentIndex = start;
        while (i<=rightStart-1 && j<=end) {
            if (a[i]<=a[j]) {
                temp[currentIndex++] = a[i++];
            } else {
                temp[currentIndex++] = a[j++];
            }
        }
        while (i<=rightStart-1) {
            temp[currentIndex++] = a[i++];
        }
        while (j<=end) {
            temp[currentIndex++] = a[j++];
        }
        for (currentIndex=start;currentIndex<=end;currentIndex++) {
            a[currentIndex] = temp[currentIndex];
        }
        System.out.println("每步打印:start="+start+", end="+end);
        print(a);
        System.out.println();
    }

    /**
     * 希尔排序
     * 时间复杂度:平均O(n^1.3),最坏O(n^2),最好O(n)(*时间复杂度与步长的选择有关)
     * 空间复杂度O(1)
     * 不稳定排序
     * @param a
     */
    private static void shellSort(int[] a) {
        if (a == null || a.length == 0 || a.length == 1) {
            return;
        }
        int gap = a.length/2; //步长
        int m=0, n=0;
        int temp = 0;
        while (gap>0) {
            // 以下是分组执行,但实际过程中是多个分组交叉执行
            /*for (int i = 0; i < gap; i++) {
                for (m = gap + i; m < a.length; m += gap) {
                    temp = a[m];
                    for (n = m-gap; n >=0; n -= gap) {
                        if (a[n] > temp) {
                            a[n + gap] = a[n];
                        } else {
                            break;
                        }
                    }
                    a[n + gap] = temp;
                }
            }*/
            for (m=gap; m<a.length;m++) {
                temp = a[m];
                for (n=m-gap; n>=0; n-=gap) {
                    if (a[n]>temp) {
                        a[n+gap] = a[n];
                    } else {
                        break;
                    }
                }
                a[n+gap] = temp;
            }

            //每步说明:
            //System.out.println("步长为"+gap+":");
            //print(a);
            //System.out.println();
            //每步说明end

            gap = gap/2;
        }

    }

    /**
     * 插入排序
     * 时间复杂度:平均O(n^2),最坏O(n^2),最好O(n)
     * 空间复杂度O(1)
     * 稳定排序
     * 适用原始数据基本有序的
     * @param a
     */
    private static void insertionSort(int[] a) {
        if (a == null || a.length == 0 || a.length == 1) {
            return;
        }
        int temp=0, i=0, j=0;
        for (i=1; i<a.length; i++) {
            temp = a[i];
            j=i-1;
            for (j=i-1;j>=0;j--) {
                if (a[j]>temp) {
                    a[j+1] = a[j];
                } else {
                    break;
                }
            }
            a[j+1] = temp;
        }
    }


    /**
     * 选择排序
     * 时间复杂度:平均O(n^2),最坏O(n^2),最好O(n^2)
     * 空间复杂度O(1)
     * 不稳定排序
     * 适用数据规模小的
     * @param a
     */
    private static void selectionSort(int[] a) {
        if (a == null || a.length == 0 || a.length == 1) {
            return;
        }
        int minIndex = 0;
        for (int i=0;i<a.length-1;i++) {
            minIndex = i;
            for (int j=i+1; j<a.length; j++) {
                if (a[minIndex] > a[j]) {
                    minIndex = j;
                }
            }
            if (i != minIndex) {
                swap(a, i, minIndex);
            }
        }
    }


    /**
     * 冒泡排序
     * 时间复杂度:平均O(n^2),最坏O(n^2),最好O(n)
     * 空间复杂度O(1)
     * 稳定排序
     * 适用原始数据基本有序的
     * @param a
     */
    private static void bubbleSort(int[] a) {
        if (a == null || a.length == 0 || a.length == 1) {
            return;
        }
        for (int i=0 ;i<a.length-1;i++) {
            boolean flag = false; //在此次遍历中是否有元素交换
            for (int j=0; j<a.length-1-i; j++) {
                if (a[j]>a[j+1]) {
                    swap(a, j, j+1);
                    flag = true;
                }
            }
            if (!flag) {
                //没有元素交换,说明已经排序完成
                break;
            }
        }
    }

    // 交换数组a中位置i和位置j的元素
    private static void swap(int[] a, int j, int i) {
        if (a == null || j>=a.length || j<0 || i>=a.length || i<0) {
            System.err.println("swap下标越界 j="+j+", i="+i);
            return;
        }
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    //打印数组
    private static void print(int[] a) {
        if (a==null || a.length ==0) {
            System.out.println("empty array");
            return;
        }
        for (int i=0;i<a.length;i++) {
            System.out.printf("%d ",a[i]);
        }
    }
}

举报

相关推荐

0 条评论