算法筆記(一) 排序之桶排序和插入排序

什麼是算法

       百度百科中的定義是這樣的,算法(Algorithm)是指解題方案的準確而完整的描述,是一系列解決問題的清晰指令,算法代表着用系統的方法描述解決問題的策略機制。
      個人理解算法是用來解決某一個或者某一列問題的方案方法,在我們的生活中算法無處無處不在,處處體現着算法的運用,比如你要去某一個目的地,到達目的地有好幾條路,我們都會自己選擇最近的路走,在這個選擇的過程中其實也用了算法。

      有大有小並不是越複雜的算法實用價值就高,一個算法的實用性是由使用該算法人的多少,解決的問題來決定的,如01揹包問題解決了當某個條件最大時,價值最大的問題;最長公共子序列解決了DNA相似性程度,爲預防疾病做出了貢獻。

算法由來

      關於算法的由來存在着集中不同的說法,一種認爲比較多的說法是來自於《波斯教科書》作者的名字,在裏面最早的含義僅僅表示數字的四則運算,並沒有今天代表的這麼多含義,在文化不斷髮展過程中1950年出來了歐幾里德運算,而且兩者慢慢練習在一起,隨後的研究過程中,逐漸把一些規律性的問題稱之爲算法Algorithm,從算法產生來看也就是80年左右的歷史,所以我們現在學習的是80年的結晶,學習算法是一件很有意義的事情。

爲什麼要學習算法

      難道我們學習算法只是爲了應付考試、用來面試、用來炫耀麼,這樣的目的顯示很世俗,但誰不想去谷歌、百度、BAT這樣的大公司呢,算法似乎是這些公司必問的一項內容,如果你懂得多就有可能得到更多的機會。

      算法就像內功修煉一樣,是一種外在表現不出來的修養,同各種類型工具、UI外在的招式相比不好修煉、有一定難度所以它經久不衰,想想從計算機誕生到現在各種技術層出不窮,如前端框架jquery、ext、bootstrap等,還有各種後端開發框架,這裏就不一一列舉了,唯一不變的就是算法,從古代武裝電視劇我們就可以得出來結論,只學習一些外在招式而不注重內在修煉很難成爲武功大成者,他們有相似的道理。
      我們從排序算法入手,看一下桶排序和插入排序。

桶排序

原理

      它的原理很好理解,數組元素值表示數字出現的次數,下標表示該數字大小,把數組打印出來就可以得到排好序的列表,它的排序速度也是很快,桶排序是最快、最簡單的排序,但它可能浪費的空間也是最多的,假如排序中最大數是10000,那麼需要分配10001長度的存放數據,裏面大部分空間是浪費的,如下圖所示:

這裏寫圖片描述

實現思路

  1. 已知有一個五個數組成的整型數組a[5,7,2,1,7],現從小到大排序
  2. 初始化元素都爲0的數據b[],最大index爲已知數組最大值+1
  3. 根據下標給b[]數組元素賦值,如果b下標每出現次b[index]+1
  4. 打印b[]數組下標(b[index]十幾就打印幾次)

java版

public static List<Integer> bucketSortedList(int[] arrayParamList){
        List<Integer> sortedInt = new ArrayList<Integer>(arrayParamList.length);

        int[] arrayBucket = new int[11];
        for (int element : arrayParamList){
            arrayBucket[element] = arrayBucket[element]+1;
        }

        for (int i = 0;i < arrayBucket.length; i++){
            if (arrayBucket[i] != 0){
                for (int j = 1;j <= arrayBucket[i];j++){
                    sortedInt.add(i);
                }
            }
        }

        return sortedInt;
    }

python 版

  1 def bucket_sort():
  2         deflist = [2,5,7,8,3,9]
  3 
  4         bucketList = []
  5         for i in range(10):
  6                 bucketList.append(0)
  7                 print("i="+str(i))
  8         for element in deflist:
  9                 bucketList[element] = bucketList[element] + 1
 10                 print("element="+str(element))
 11 
 12         result = []
 13         for j in range(len(bucketList)):
 14                 print("j="+str(j))
 15                 if (bucketList[j] != 0):
 16                         for t in range(bucketList[j]):
 17                                 result.append(j)
 18         return result
 19 

插入排序

原理

      插入排序的原理是通過不斷比較不斷尋找元素的最適合插入位置,爲每一個元素和前面的元素比較,如果不符合排序規則,則交換位置,有一個網站上面有一棟的動態圖,幫助我們理解一棟過程,下面是一個靜態圖,它是按從小到大排序第一次12和15比較,12<15故不進行移動;第二次9移動到了首位置,其它這裏比較了兩次分爲和12、15,由於9小於12、15,兩次交換位置,插入排序優點是快,但是比較次數不能確定,最壞是將遞增序列按遞減排,每個元素都需要移動和比較,如下圖:

這裏寫圖片描述

實現思路

  1. 訪問每次元素,確定它的位置是否正確
  2. 當前元素與前面元素逐個比較,找到自己的合適位置
  3. 每個元素都找好位置之後,排序也就排好了

java代碼

public static int[] insertSortedList(int[] arrayParamList){

        for (int i = 1; i < arrayParamList.length;i++){
            System.out.println("i="+i);
            //循環計數變量
            int j = i - 1;
            //欲插入數據變量
            int target = arrayParamList[i];

            //錯誤代碼
//            for (j=i-1;j >= 0 ;j--){
//                if (arrayParamList[j] > target){
//                    arrayParamList[j+1] = arrayParamList[j];
//                }
//            }
            //找適當的插入位置
            while (j>=0 && arrayParamList[j] > target){
                arrayParamList[j+1] = arrayParamList[j];
                j--;
            }
            //將變量插入
            arrayParamList[j+1]=target;
        }

        return arrayParamList;
    }

      開始在寫代碼時,位置比較和交換利用for () {}循環比較的,發現總是不對,問題在於每次循環之後j都會自動減1,也就是說不小於時也往前移動了,這就會有問題,這裏使用while循環還是比較合適的,滿足比較天劍才移動位置,算法代碼要多寫、多思考才能更完善。

python代碼

  1 def insert_sort():
  2         defList = [7,4,8,2,4,5]
  3         print("length="+str(len(defList)))
  4         for i in range(1,len(defList)):
  5                 print("i="+str(i))
  6                 j = i - 1
  7                 target = defList[i]
  8                 while j >= 0 and defList[j] > target :
  9                         defList[j+1] = defList[j]
 10                         j -= 1
 11                 defList[j+1] = target
 12 
 13         for m in defList:
 14                 print("m="+str(m))
 15 

總結

      經常學習有益於大腦活躍,開發智力提神益腦;算法有助我們提高編碼質量、效率;它是一種幾百年智慧的結晶,從小裏面說懂算法的人也是懂生活的人,算法裏面蘊含着很多優秀思想,需要慢慢體會理解,然後運用到工作、生活中去。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章