《算法圖解》中涉及的算法的總結及java實現

該項目源代碼已經放到Github上,有興趣能夠點擊AlgorithmGraphExample 進行訪問git

項目啓動,項目使用maven搭建,若是不使用maven導入,請保證有Junit4的jar包在工程中.
將項目導入相應IDE,執行AlgorithmInGraphTest的showAlgorithm()方法,便可以執行相應的測試方法.github

二分查找:

算法目的: 查找在有序數組中某給定值的位置
算法原理: 當數組中元素有序排列時,經過比較數組中間位置的值和****給定值****的大小,
能夠肯定給定值在由中央位置分割而成的兩個數組的哪個部分,依次切割就能找到給定值的位置;
算法複雜度: O(logn)
算法難點:
須要肯定循環的邊界條件。
算法實現:算法

private int doBinarySearch(int [] sortedArray,int value){
        int right = sortedArray.length - 1;
        int left = 0;
        int middle;
        //這裏=號容易被忽略
        while(right>= left){
            middle = (left+right)/2;
            if(sortedArray[middle] == value){
                return middle;
            }
            else if(sortedArray[middle] < value){
                left = middle+1;
            }
            else{
                right = middle-1;
            }
        }
        return -1;
    }

選擇排序

算法目的: 將數組正確排序
算法原理: 依次選擇最小(大)的值放到對應的位置
算法複雜度: O(n^2)
算法難點::無
算法實現:數組

private void sort(int [] array){
            for(int i = 0;i<array.length;i++){
                int min = array[i];
                int index = i;
                for(int j = i;j<array.length;j++){
                    if(min > array[j]){
                        min = array[j];
                        index = j;
                    }
                }
                if(i != index){
                    int temp = array[i];
                    array[i] = array[index];
                    array[index] = temp;
                }
            }
        }

快速排序--分治

算法目的: 將數組正確排序
算法原理: 準一個基準值(通常選擇數組中第一個值),將數組分紅兩部分,前一部分比基準值小,後一部分比基準值大.
而後將分割後的兩個數組繼續按這個方式分割,一直到子數組只剩下一個值,那麼全部子數組都是排序好的,最後彙總起來也是排序好的數組
算法複雜度: O(n^2)
算法難點::無
算法實現:maven

private void quickSort(int [] array,int start,int end){
        if(start >= end){
            return;
        }
        int left = start;
        int right = end;
        int value = array[start];
        while(left < right){
            while(array[right] > value && left < right)
                right--;
            array[left] = array[right];
            while(array[left] < value && left < right)
                left++;
            array[right] = array[left];
        }
        array[left] = value;
        quickSort(array,left+1,end);
        quickSort(array,start,left-1);

    }

廣度優先搜索--圖算法 最短路徑

算法目的: 遍歷圖中節點的一種方法,能夠找到兩節點的最短路徑
算法原理: 圖的搜索算法,對每一個節點:搜索其子節點(相連節點),若是該節點被搜索過,那麼就跳過,不然加入到搜索節點隊列;當前節點完成後,從隊列中選擇
第一個節點繼續搜索.直到隊列中再也不有節點.
算法複雜度:
算法難點::無
算法實現:測試

int point_num = graph[0].length;

        List<Integer> result = new ArrayList<Integer>();

        Queue<Integer> queue = new LinkedList<Integer>();
        List<Integer> searchedList = new ArrayList<Integer>();    //已經查找過的點
        queue.offer(0);
        searchedList.add(0);

        int index = 0;

        while(!queue.isEmpty()){
            Integer currentPoint = queue.poll();
            result.add(currentPoint);
            for(int i = 0;i<graph[currentPoint].length;i++){
                if(!searchedList.contains(i) && graph[currentPoint][i] == 1){
                    queue.offer(i);
                    searchedList.add(i);
                }
            }

        }
        return result;

迪傑斯特拉算法

算法目的: 在有向無環的帶權值的圖中,找出權值最短的路徑
算法原理: 由於是有向圖而且無環,做爲基準的點,當時的權值都是起點到這些節點最小的時候.
算法難點::無
算法實現:ui

while (continueSeach) {
                    continueSeach = false;
                    for (int i = 0; i < length; i++) {
                        if (graph[currentNode][i] < 0) {
                            continue;
                        }
                        if (graph[currentNode][i] + minimumValue[currentNode] < minimumValue[i]) {
                            minimumValue[i] = graph[currentNode][i] + minimumValue[currentNode];
                            minmimumNode[i] = currentNode;
                        }
                    }
                    //已經檢查過的節點
                    examinedNode.add(currentNode);
        
                    //從當前節點中選擇一個最小的節點值
                    int minmum = Integer.MAX_VALUE;
                    for (int i = 0; i < length; i++) {
                        if (!examinedNode.contains(i) && minimumValue[i] < minmum) {
                            currentNode = i;
                            minmum = minimumValue[i];
                            continueSeach = true;
                        }
                    }
                }

揹包問題--貪心算法

算法目的: 對於一個固定重量的揹包,裝入一組重量和大小固定的物品,物品能夠只放入部分,能夠求出如何放置得出的值最大
算法原理: 物品可拆分,只要依次裝入單位價值最大的物品便可.貪心算法的原理是每次的操做都是最優的,只有一個操做.
算法實現:code

while(i<weighs.length){
                    if(currentWeight + weighs[i] < maxWeight){
                        currentWeight += weighs[i];
                        maxValue += value[i];
        
                    }else {
                        maxValue += value[i] ** (maxWeight - currentWeight) / weighs[i];
                        break;
                    }
                    i++;
                }

01揹包--動態規劃

算法目的: 對於一個固定重量的揹包,裝入一組重量和大小固定的物品,物品只能完整放入或者不放入,能夠求出如何放置得出的值最大
算法原理: 物品不可拆分,因此不能使用貪心算法,由於若是當次放入單位價值最大的物品可能致使後面總體價值最大的物品沒法房屋.
若是較大問題的最優解包含了較小問題的最優解,那麼就可使用動態規劃來作.
動態規劃問題的核心是當前問題的最優解包含在小規模的最優解中,或者說大規模問題能夠由小規模問題推導出來,也就是狀態轉移;
具體到0,1揹包;狀態轉移爲:對於第i件物品,在揹包容量限定爲weight的狀況下,其最大價值在放這件物品與不放這件物品之間選擇一個:
a:若是放的話,那麼價值爲當前揹包容量減去該物品重量後能放置物品的最高價值與當前物品的價值累加;就是數組中a[i-1][weight-weighs[i]]
b: 若是不放的話,那麼價值就應該是當前揹包容量下不考慮這個物品,也就是上個物品在該揹包容量的最大價值:也就是數組中a[i-1][weight]
a與b的最大值就是當前規模的最優值
算法實現:排序

for(int i=0;i<weighs.length;i++){
                    for(int j=0;j<maxWeight;j++){
                        //初始化
                        if(i==0){
                            if(j >= weighs[0]){
                                currentState[i][j] = value[0];
                            }
                        }else if(j >= weighs[i] ){
                            if(currentState[i-1][j-weighs[i]]+value[i] > currentState[i-1][j]){
                                currentState[i][j] = currentState[i-1][j-weighs[i]]+value[i];
                            }else{
                                currentState[i][j] = currentState[i-1][j];
                            }
                        }
                        else{
                            currentState[i][j] = currentState[i-1][j];
                        }
                        if(maxResult < currentState[i][j]){
                            maxResult = currentState[i][j];
                        }
                    }
                }
相關文章
相關標籤/搜索