數據結構與算法簡述(下)

目錄:

  • 算法簡介
  • 排序算法
  • 遞歸與窮舉
  • 貪心與分治
  • 動態規劃和回溯

1.算法簡介

解題方案的準確而完整的描述,是一系列解決問題的清晰指令。

特征

  • 有窮性
  • 確切性
  • 輸入項
  • 輸出項
  • 可行性

算法優劣評定

  • 時間復雜度
  • 空間復雜度
  • 正確性
  • 可讀性
  • 健壯性

2.算法排序

2.1 插入排序
  • 冒泡排序
public static void main(String [] args){
        int[] a = {49,38,65,97,23,22,76,1,5,8,2,0,-1};
        //直接插入排序開始
        for(int i = 1;i<a.length;i++){
            int temp = a[i];//新遍歷的值,等待插入到前面的有序數組
            int j;
            for(j = i-1;j>=0;j--){
                //將大于temp的數往后面移一步
                if(a[j]>temp){
                    a[j+1] = a[j];
                }else{
                    break;
                }
            }
           //break數據代表j處數據小于temp,j之前的數據又是從小到大排列,所以temp就放在j后面
            a[j+1] = temp;
        }
        System.out.println("排序后:");
        for(int i = 0;i<a.length;i++){
            System.out.println(" "+a[i]);
        }
    }

時間復雜度:O(N^2)

  • 二分法排序

時間復雜度:O(logN)

  • 希爾排序

時間復雜度:O(N^(3/2))

2.2 選擇排序
  • 簡單選擇排序

時間復雜度:O(N^(3/2))

  • 堆排序
    //堆排序
    public static void main(String[] args){
        int[] array = {39,44,1,0,8,66,23,67,9,15,100,70,22,3,6,54};
        HeapSort heapSort = new HeapSort();
        heapSort.heapSort(array);
        for(int i = 0;i<array.length;i++){
            System.out.println(" "+array[i]);
        }
    }
    
    public void heapSort(int [] a){
        if(a == null||a.length<=1){
            return;
        }
        //創建大堆
        buildMaxHeap(a);
        for(int i = a.length-1;i>=1;i--){
            //最大元素已經排在了下標為0的地方
            exchangeElements(a, 0, i);//每交換換一次,就沉淀一個大元素
            maxHeap(a, i, 0);
        }
    }

    
    private void buildMaxHeap(int[] a) {
        int half = (a.length -1)/2;//假設長度為9
        for(int i = half;i>=0;i--){
            //只需遍歷43210
            maxHeap(a,a.length,i);
        }
    }

    //length表示用于構造大堆的數組長度元素數量
    private void maxHeap(int[] a, int length, int i) {
        int left = i*2+1;
        int right = i*2+2;
        int largest = i;
        if(left<length&&a[left]>a[i]){
            largest = left;
        }
        if(right<length&&a[right]>a[largest]){
            largest = right;
        }
        if(i!=largest){
            //進行數據交換
            exchangeElements(a,i,largest);
            maxHeap(a, length, largest);
        }
    }

    //在數組a里進行兩個下標元素交換
    private void exchangeElements(int[] a, int i, int largest) {
        int temp = a[i];
        a[i] = a[largest];
        a[largest] = temp;
    }

時間復雜度:O(NlogN)

2.3 交換排序
  • 快速排序
    /**
     * 快速排序
     * 
     * @param a
     * @param i
     * @param j
     */
    private void quickSort(int[] a, int low, int high) {
        if (low < high) {
            int middle = getMiddle(a, low, high);
            quickSort(a, 0, middle - 1);
            quickSort(a, middle + 1, high);
        }
    }

    /**
     * 獲取中間下標
     * 
     * @param a
     * @param low
     * @param high
     * @return
     */
    private int getMiddle(int[] a, int low, int high) {
        int temp = a[low];// 基準元素
        while (low < high) {
            while (low < high && a[high] >= temp) {
                high--;
            }
            a[low] = a[high];
            while (low < high && a[low] <= temp) {
                low++;
            }
            a[high] = a[low];
        }
        a[low] = temp;// 插入到排序后正確的位置
        return low;
    }

    public static void main(String[] args) {
        QuickSort quickSort = new QuickSort();
        int[] a = { 19, 2, 3, 90, 67, 33, -7, 24, 3, 56, 34, 5 };
        quickSort.quickSort(a, 0, a.length - 1);
        for (int num : a) {
            System.out.println(" " + num);
        }
    }

時間復雜度:O(NlogN)

2.4 歸并排序
    //歸并排序
    public void mergeSort(int[] a, int left, int right) {
        if (left < right) {
            int middle = (left + right) / 2;
            mergeSort(a, left, middle);
            mergeSort(a, middle + 1, right);
            merge(a, left, middle, right);// 合并
        }
    }

    private void merge(int[] a, int left, int middle, int right) {
        int[] tmpArray = new int[a.length];
        int rightStart = middle + 1;
        int tmp = left;
        int third = left;
        // 比較兩個小數組相應下標位置的數組大小,小的先放進新數組
        while (left <= middle && rightStart <= right) {
            if (a[left] <= a[rightStart]) {
                tmpArray[third++] = a[left++];
            } else {
                tmpArray[third++] = a[rightStart++];
            }
        }
        // 如果左邊還有數據需要拷貝,把左邊數組剩下的拷貝到新數組
        while (left <= middle) {
            tmpArray[third++] = a[left++];
        }
        // 如果右邊還有數據......
        while (rightStart <= right) {
            tmpArray[third++] = a[rightStart++];
        }
        while (tmp <= right) {
            a[tmp] = tmpArray[tmp++];
        }
    }

    public static void main(String[] args) {
        MergeSort mergeSort = new MergeSort();
        int[] a = new int[] { 90, 3, 2, 67, 44, -9, 87, 65, 11, 9, 2, 8 };
        mergeSort.mergeSort(a, 0, a.length - 1);
        for (int n : a) {
            System.out.print(" " + n);
        }
    }

時間復雜度:O(NlogN)

2.5 基數排序
    public void sort(int[] array) {
        int max = 0;// 獲取最大值
        for (int i = 0; i < array.length; i++) {
            if (max < array[i]) {
                max = array[i];
            }
        }
        int times = 0;// 獲取最大值位數
        while (max > 0) {
            max = max / 10;
            times++;
        }
        List<ArrayList> queue = new ArrayList<ArrayList>();// 多維數組
        for (int i = 0; i < 10; i++) {
            ArrayList<Object> q = new ArrayList<>();
            queue.add(q);
        }
        for (int i = 0; i < times; i++) {
            for (int j = 0; j < array.length; j++) {
                // 獲取對應的位的值(i為0是個位,1是10位,2是百位)
                int x = array[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
                ArrayList<Integer> q = queue.get(x);
                q.add(array[j]);// 把元素添加進對應下標數組
                // queue.set(x,q);//待定
            }
            // 開始收集
            int count = 0;
            for (int j = 0; j < 10; j++) {
                while (queue.get(j).size() > 0) {
                    ArrayList<Integer> q = queue.get(j);// 拿到每一個數組
                    array[count] = q.get(0);
                    q.remove(0);
                    count++;
                }
            }
        }
    }

    public static void main(String[] args) {
        BasicSort basicSort = new BasicSort();
        int[] a = { 136, 2, 6, 8, 9, 2, 8, 11, 23, 56, 34, 90, 89, 29, 145, 209, 320, 78, 3 };
        basicSort.sort(a);
        for (int n : a) {
            System.out.print(" " + n);
        }
    }

時間復雜度:O(NlogN)

3.遞歸與窮舉

  • 二分法查找

4.貪心與分治

5.動態規劃和回避

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容