什麼是算法
百度百科中的定義是這樣的,算法(Algorithm)是指解題方案的準確而完整的描述,是一系列解決問題的清晰指令,算法代表着用系統的方法描述解決問題的策略機制。
個人理解算法是用來解決某一個或者某一列問題的方案方法,在我們的生活中算法無處無處不在,處處體現着算法的運用,比如你要去某一個目的地,到達目的地有好幾條路,我們都會自己選擇最近的路走,在這個選擇的過程中其實也用了算法。
有大有小並不是越複雜的算法實用價值就高,一個算法的實用性是由使用該算法人的多少,解決的問題來決定的,如01揹包問題解決了當某個條件最大時,價值最大的問題;最長公共子序列解決了DNA相似性程度,爲預防疾病做出了貢獻。
算法由來
關於算法的由來存在着集中不同的說法,一種認爲比較多的說法是來自於《波斯教科書》作者的名字,在裏面最早的含義僅僅表示數字的四則運算,並沒有今天代表的這麼多含義,在文化不斷髮展過程中1950年出來了歐幾里德運算,而且兩者慢慢練習在一起,隨後的研究過程中,逐漸把一些規律性的問題稱之爲算法Algorithm,從算法產生來看也就是80年左右的歷史,所以我們現在學習的是80年的結晶,學習算法是一件很有意義的事情。
爲什麼要學習算法
難道我們學習算法只是爲了應付考試、用來面試、用來炫耀麼,這樣的目的顯示很世俗,但誰不想去谷歌、百度、BAT這樣的大公司呢,算法似乎是這些公司必問的一項內容,如果你懂得多就有可能得到更多的機會。
算法就像內功修煉一樣,是一種外在表現不出來的修養,同各種類型工具、UI外在的招式相比不好修煉、有一定難度所以它經久不衰,想想從計算機誕生到現在各種技術層出不窮,如前端框架jquery、ext、bootstrap等,還有各種後端開發框架,這裏就不一一列舉了,唯一不變的就是算法,從古代武裝電視劇我們就可以得出來結論,只學習一些外在招式而不注重內在修煉很難成爲武功大成者,他們有相似的道理。
我們從排序算法入手,看一下桶排序和插入排序。
桶排序
原理
它的原理很好理解,數組元素值表示數字出現的次數,下標表示該數字大小,把數組打印出來就可以得到排好序的列表,它的排序速度也是很快,桶排序是最快、最簡單的排序,但它可能浪費的空間也是最多的,假如排序中最大數是10000,那麼需要分配10001長度的存放數據,裏面大部分空間是浪費的,如下圖所示:
實現思路
- 已知有一個五個數組成的整型數組a[5,7,2,1,7],現從小到大排序
- 初始化元素都爲0的數據b[],最大index爲已知數組最大值+1
- 根據下標給b[]數組元素賦值,如果b下標每出現次b[index]+1
- 打印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,兩次交換位置,插入排序優點是快,但是比較次數不能確定,最壞是將遞增序列按遞減排,每個元素都需要移動和比較,如下圖:
實現思路
- 訪問每次元素,確定它的位置是否正確
- 當前元素與前面元素逐個比較,找到自己的合適位置
- 每個元素都找好位置之後,排序也就排好了
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
總結
經常學習有益於大腦活躍,開發智力提神益腦;算法有助我們提高編碼質量、效率;它是一種幾百年智慧的結晶,從小裏面說懂算法的人也是懂生活的人,算法裏面蘊含着很多優秀思想,需要慢慢體會理解,然後運用到工作、生活中去。