1. 程式人生 > 其它 >演算法思維:二分思想,捨棄思想,遞迴樹思想

演算法思維:二分思想,捨棄思想,遞迴樹思想

一個歸併排序+遞迴帶來的思考.

前言

  • 思想:二分思想,捨棄思想,遞迴樹思想,
  • 重點:數軸,樹思想,棧思想,二分,多分思想,master公式
  • 一遇遞迴,直接造樹!!
  • 遞迴,永遠不要把它當作一個方法,你可以把它當作一個過程樹

先想想遞迴最大值:

  • 1.[L,R]上求最大值

    • 定:遞迴求最大,數軸,拆分為樹
    • 解:
      • 1.二分思想,兩個跑肯定比單個跑快--那麼就涉及到中間,中間數的求法最好就是捨棄法
      • 2.中間為分界,左邊跑,右邊跑
      • 3.呼叫Math函式進行比較
      • 思維解:
        • 1.多叉樹,2.利用棧後繼遍歷.3.懸而未決壓入棧 4.清晰的就出去 5.高度上壓棧
          • 懸而未決(有的孩子(子節點)不知道是多少)
          • 棧---
    • 規範:只有一個數?直接處理
    • 注:Math雖然好用,但只能用於判斷回值.資料的交換,還是需交換方式,
  • 2.遞迴的master公式---(重點)

    • 定:遞迴的複雜度,遞迴的執行流程
    • 解:
      • 1.先樹,棧的形式解析整個遞迴 ---發現樹的高度就是遞迴的次數
      • 2.master公式的學習
        • T(N)=a*(N/b)+O(N^d)
        • 主方法 = 次數*子方法+其它 --- 遞迴的主方法和子方法也就名字不一樣
        • a指的是呼叫方法次數,b指的是切割問題幾段,,N指的是複雜度
      • 3.時間複雜度的計算
        • 1.log(b,a)>d--->複雜度O(N^log(b,a))
        • 2.log(b,a)複雜度O(N^d)
        • 3.log(b,a)==d--->複雜度O(O^d * logN)
  • 一般使用遞迴是為了職責分明,遞迴就進棧,彈棧就好了,彈棧是由自己寫的條件控制.有多子遞迴時,那就樹來走

歸併

本質:二分排序,再合併

  • 歸併的做法是:左側比較完,右側比較完,再最後左右比較
  • 還是兩兩交換,,不管是for迴圈,還是遞迴---兩者都是使用二分思想來變成O(logN),本質是讓兩個數兩兩互動排序

歸併遞迴法

  • 我測試了它的遞迴走向
    • 發現它的走向是按照(終止條件,方法體控制的),遞迴的本質是都走
    • 怎麼走,就是如果裡面是雙子遞迴,那麼它會按樹走,走的時候,是先左大節點,再左大節點的左子節點,再左大節點的右子節點.(往復進行),中途走到終止條件跳出,
      其它繼續執行,,遇到很小的滿足要求方法體的也會去執行.
  • 它的目的就是,整個流程我都整出來並且壓入棧,執行完的或者遇到條件的就出去,按照你的控制停止,你有條件,滿足就執行.

必須明白的遞迴彈棧

  • 開始,進棧[0,7],遇到子,再進棧[0,3],遇到子,再進棧[0,1],再遇到再進,直到遇到該停止的,再不斷的彈,彈出這一步,走下一步,下一步再彈,再...

  • 簡單沒有彈,只是順序執行的流程

       這是一個,沒有終止彈棧的流程
        原資料:11,8,9,4,12,3,7,6
        遞迴流程:0--1
        方法執行:8 11 
        遞迴流程:2--3
        方法執行:4 9 
        遞迴流程:0--3
        方法執行:4 8 9 11 
        遞迴流程:4--5
        方法執行:3 12 
        遞迴流程:6--7
        方法執行:6 7 
        遞迴流程:4--7
        方法執行:3 6 7 12 
        遞迴流程:0--7
        方法執行:3 4 6 7 8 9 11 12 
        輸出結果:3 4 6 7 8 9 11 12 
    
    
  • 歸併排序程式碼:

    
        public class MergeSortTest {
            
            // 解---由大到小解決,
            // 1.解遞迴
          // 0,R都是陣列下標
            public void process(int arr[],int L,int R){
                if(L==R){   // 結束標誌,也就是葉子節點結束
                    return;
                }
                int m = L+((R-L)>>1);
                process(arr,L,m);            //----L----m-----R--  不僅僅一個,是樹
                process(arr,m+1,R);
               /* System.out.println("遞迴流程"+":"+L + "--" + R);*/
                merge(arr,L,m,R);
    
    
            }
    
            // 2.解排序--按照最基本的葉子進行計算,滿足最基本的LMR的葉子進行思考,如 529
    
    
            public void merge(int arr[],int L,int M,int R){
                // 定:要使得兩邊有序 ---
                // 解:最基本的葉子,529---
                // 需求:指標,[L,M]邊的,[M,R]邊的
                int p1 = L;
                int p2 = M+1;
                // 輔助陣列存值
                int help[] = new int[R-L+1];
                int i = 0; // 輔助的指標
                // 節點卡標
                while (p1 <= M && p2 <= R){ // 有一個指標滿足就停止
                    help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];  // 此時必定會將一邊的全打進去
                }
    
    
                while (p1 <= M){
                    help[i++] = arr[p1++];
                }
    
                while (p2 <= R){
                    help[i++] = arr[p2++];
                }
    
                for (int j = 0; j < help.length; j++) {
                    arr[L+j] = help[j];
                }
    
        /*
                // merge方法體流程!
                System.out.print("方法執行:");
                for (int i1 : help) {
                    System.out.print(i1+" ");
                }
                System.out.println();
        */
    
            }
    
    
            public static void main(String[] args) {
                MergeSortTest mergeSortTest = new MergeSortTest();
                int arr[] = new int[]{11,8,9,4,12,3,7,6};
                System.out.println("原資料:"+ "11,8,9,4,12,3,7,6");
                mergeSortTest.process(arr,0,arr.length-1);
                System.out.print("輸出結果:");
                for (int i : arr) {
                    System.out.print(i+" ");
                }
            }
        }    
      
    

本文來自部落格園,作者:{zjz},轉載請註明原文連結:{https://www.cnblogs.com/zjz0818/}