程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 算法怎麼就這麼難---歸並排序和快速排序

算法怎麼就這麼難---歸並排序和快速排序

編輯:C++入門知識

算法怎麼就這麼難---歸並排序和快速排序


最近學了幾天基礎的數據結構的知識,越學越為自己的智商捉急了,再看看好多大牛的一些關於算法的博客,真心覺得差距是這麼這麼大。好了,廢話不多少了,接下來我簡要講述一下兩個基本的排序:歸並排序和快速排序:   歸並排序 歸並排序的原理:歸並排序是將一個集合分成兩部分:part1和part2,分別對part1和part2進行排序(使用遞歸法,直到子集合的大小為1,則停止將集合拆分,此時因為子集合中只有一個元素,所以,這個子集合也就相當於已經拍好了順序),最後將這兩部分排好順序的集合合並為一。   在編寫代碼的時候有幾個注意點:   如何將集合分成兩部分,各大小都為多少? 集合的第一部分為list.length/2;集合的第二部分為list.length-list.length/2;   集合的遞歸調用什麼時候停止? 當子集合的大小為1時,則停止對集合劃分,故在方法的一開始應該加上一個判斷   If(list.length > 1){   };   代碼實現:   public static void mergeSort(int[] list){           if(list.length > 1){               int[] half1 = new int[list.length/2];               int[] half2 = new int[list.length - list.length/2];               System.arraycopy(list, 0, half1, 0, half1.length); //將集合的前半部分復制到half1中               mergeSort(half1);               System.arraycopy(list, list.length/2, half2, 0, half2.length); //將集合的後半部分復制到half2中               mergeSort(half2);                              int[] temp = merge(half1,half2); //將兩個集合合並               System.arraycopy(temp, 0, list, 0, temp.length);           }       }   上段代碼的merge方法的作用是將兩個集合合並為一個並返回。   代碼實現:   private static int[] merge(int[] list1, int[] list2){           int[] temp = new int[list1.length + list2.length];           int currentPosition1 = 0; //遍歷list1時使用的下標變量           int currentPosition2 = 0; //遍歷list2時使用的下標變量           int currentPositionTemp = 0; //合並兩個list時使用的下標變量               //將兩個集合中的元素copy到臨時變量中   while(currentPosition1 < list1.length && currentPosition2 < list2.length){             if(list1[currentPosition1] < list2[currentPosition2]){ //將小的元素放到前面。                   temp[currentPositionTemp++] = list1[currentPosition1++];               }else               {                   temp[currentPositionTemp++] = list2[currentPosition2++];               }           }           //運行到此處時,list1和list2中的至少其中一個list已經全部復制到臨時集合中,但有可能list1中元素的數量小於list2中元素   //的數量,因此,需要將list1或者list2中的剩余的數據復制到臨時集合中。           while(currentPosition1 < list1.length){               temp[currentPositionTemp++] = list1[currentPosition1++];           }           while(currentPosition2 < list2.length){               temp[currentPositionTemp++] = list2[currentPosition2++];           }           return temp;       }       測試代碼:   public static void main(String[] args) {           // TODO Auto-generated method stub           int[] list = {1,29,1,2,90,1,0};           mergeSort(list);           for(int temp : list){               System.out.print(temp + " ");           }           System.out.println();       }   運行結果:               快速排序 快速排序的原理:快速排序在數組中選擇一個稱為主元(pivot)的元素將數組分成兩個部分,使得第一部分的所有元素小於或等於主元(pivot),而第二部分的所有元素均大於主元(pivot)。然後對第一部分遞歸得應用快速排序算法,然後對第二部分遞歸得應用快速排序算法。   Pivot的英文意思為中心點,所以,快速排序可以理解為找中心點,然後根據中心點,將數組分成兩部分,一部分小於或等於中心點,另一部分大於中心點,然後按照此方法對兩個部分分別執行,最後就將數組排好了順序。   為了簡單起見,接下來我的代碼實現中,將數組的第一個元素作為中心點(pivot)。   代碼如下:   說明:此段代碼的功能是根據集合的第一個元素作為中心點(pivot)將集合分成兩個部分,返回中間點pivot的下標   private static int partition(int[] list, int first, int last){   //參數first和last用於指定,將集合的哪一段按照pivot分成兩部分。           int pivot = list[first]; //取第一個元素作為集合的中心點(pivot)           int low = first + 1;           int high = last;                      while(high > low){   //找到從前向後數第一個大於pivot的元素,然後找到從後向前數第一個小於pivot的元素,將他們兩個互換               while(low <= high && list[low] <= pivot)                   low++;                              while(low <= high && list[high] > pivot){                   high--;               }               if(high > low){                   int temp = list[high];                   list[high] = list[low];                   list[low] = temp;               }           }   //經過上面一個循環之後,下標小於low的元素均小於pivot,小標大於high的元素均大於pivot               //將high的下標從後向前遍歷,直到找到當前下標的值小於等於pivot為止           while(high > first && list[high] >= pivot){               high--;           }                      if(pivot > list[high]){//if成立,表示pivot的值不是集合中最小的值,此時將pivot的值放到list[high]的位置上               list[first] = list[high];               list[high] = pivot;               return high;           }else{ //此種情況表示,pivot為集合中最小的元素,因此,pivot值的小標也就是first               return first;           }       }   quicksort()代碼如下:   private static void quickSort(int[] list, int first, int last){           if(last > first){               int pivotIndex = partition(list,first,last);               quickSort(list,first,pivotIndex -1);               quickSort(list,pivotIndex+1,last);           }       }   此時,定義一個只有一個集合作為參數的公共方法:   public static void quickSort(int[] list){           quickSort(list,0,list.length-1);       }           測試代碼:   public static void main(String[] args) {           // TODO Auto-generated method stub           int[] list = {12,3,2,1,5,2};           quickSort(list);           for(int temp : list){               System.out.print(temp + " ");           }           System.out.println();       }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved