《啊哈!算法》笔记_Day01
臨近畢業季,在跳蚤市場收了一本**《啊哈!算法》**,我之前是沒有學過算法的,之間就知道這本書的存在,所以看見了它,就毫不猶豫地買它!!!一邊看一邊寫寫博客,保留一下自己的學習歷程ovo!
此篇文章字數有點長,請謹慎觀看
第1章、一大波數正在靠近——排序
第一節 最快最簡單的排序——桶排序(簡化版)
適用于數少,且連續的整數排序,出現一個數字i就將數組的i號元素加1,最后i號元素的值就是i出現的次數,從大到小輸出,從小到大輸出都可以。
#include <stdio.h> int main() { int a[11],i,j,t; for(i=0;i<=10;i++) a[i]=0; //初始化為0 for(i=1;i<=5;i++) //循環讀入5個數{ scanf("%d",&t); //把每一個數讀到變量t中a[t]++; //進行計數} for(i=0;i<=10;i++) //依次判斷a[0]~a[10] for(j=1;j<=a[i];j++) //出現了幾次就打印幾次printf("%d ",i); getchar();getchar(); //這里的getchar();用來暫停程序,以便查看程序輸出的內容//也可以用system("pause");等來代替return 0; }每一個桶的作用就是“標記”每個數出現的次數。
該算法的時間復雜度是 O(m+n+m+n),即 O(2*(m+n))。我們在說時間復雜度的時候可以忽略較小的常數,最終桶排序的時間復雜度為O(m+n)。還有一點,在表示時間復雜度的時候,n 和 m通常用大寫字母即 O(M+N)。M為桶的個數,N為待排序的個數。
這是一個非常快的排序算法。
桶排序從 1956 年就開始被使用,該算法的基本思想是由E.J.Issac 和 R.C.Singleton
提出來的。之前我說過,其實這并不是真正的桶排序算法,真正的桶排序算法要比這個更加復雜。
如果要排序的數還對應一個名字,數從高到低排序,并且輸出他們的名字。數使用桶排序后,怎樣把名字對應輸出呢?
這個問題可以用C語言的結構體或者Java的類來實現。
優點:非常快
缺點:排序數的范圍大時浪費空間,不方便為小數排序
第二節 鄰居好說話——冒泡排序
冒泡排序的基本思想是:每次比較兩個相鄰的元素,如果他們的順序錯誤就把它們交換過來。
(1)遍歷原始數據,從第一個數開始,到倒數第二個數結束,比較這個數和下一個數的大小,如果這個數比下一個數大,則交換這兩個數。這樣便可以將數據中最大的數轉移到數組的最后。
(2)之后再次遍歷原始數據,但是變為從第一個數開始,到倒數第三個數結束,比較這個數和下一個數的大小,如果這個數比下一個數大,則交換這兩個數。這樣便可以將第二大的數轉移到數組的倒數第二位。
(3)重復執行上述過程,一直到從第一個數開始,到第二個數結束,從而完成了排序過程。
由于這個循環過程就像泡泡上浮的過程,所以被稱為冒泡排序法。
冒泡排序的核心部分是雙重嵌套循環。冒泡排序的時間復雜度是 O(N2)。這是一個非常高的時間復雜度。冒泡排序早在 1956
年就有人開始研究,之后有很多人都嘗試過對冒泡排序進行改進,但結果卻令人失望。如 Donald E. Knuth(中文名為高德納,1974
年圖靈獎獲得者)所說:“冒泡排序除了它迷人的名字和導致了某些有趣的理論問題這一事實之外,似乎沒有什么值得推薦的。"
第三節 最常用的排序——快速排序
(1)從數列中挑出一個元素,稱為 “基準”(pivot);
(2)重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的后面(相同的數可以到任一邊)。在這個分區退出之后,該基準就處于數列的中間位置。這個稱為分區(partition)操作;
(3)遞歸地(recursive)把小于基準值元素的子數列和大于基準值元素的子數列排序;
快速排序由 C. A. R. Hoare(東尼·霍爾,Charles Antony Richard Hoare)在 1960年提出,之后又有許多人做了進一步的優化。如果你對快速排序感興趣,可以去看看東尼·霍爾1962 年在 Computer Journal發表的論文“Quicksort”以及《算法導論》的第七章。
第四節 小哼買書
這一節講的主要是去重排序,以n個正整數為例,進行去重排序。
解決這個問題的方法大致有兩種。第一種方法:先將這 n 個整數去重,再進行從小到大排序并輸出;第二種方法:先從小到大排序,輸出的時候再去重。這兩種方法都可以。
(1)先來看第一種方法。桶排序稍加改動正好可以起到去重的效果:
這種方法的時間復雜度就是桶排序的時間復雜度:O(N+M);M為桶的個數,N為待排序的個數。
(2)第二種方法我們需要先排序再去重。排序我們可以用冒泡排序或者快速排序。
先排序,相同的數都會緊挨在一起。只要在輸出的時候,預先判斷一下當前這個數 a[i]與前面一個數 a[i-1]是否相同。如果相同則表示這個數之前已經輸出過了,不用再次輸出;不同則表示這個數是第一次出現,需要輸出這個數。
這種方法的時間復雜度由兩部分組成,一部分是冒泡排序的時間復雜度,是 O(N2),另一部分是讀入和輸出,都是 O(N),因此整個算法的時間復雜度是 O(2N+N2)。相對于 N2來說,2N 可以忽略(我們通常忽略低階),最終該方法的時間復雜度是 O(N2)。
以上三種排序算法的時間復雜度。桶排序是最快的,它的時間復雜度是O(N+M);冒泡排序是 O(N2);快速排序是O(NlogN)。
謝謝你的堅持閱讀ovo喲,讓我們一起加油吖
總結
以上是生活随笔為你收集整理的《啊哈!算法》笔记_Day01的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS基础_Day04
- 下一篇: 应用视觉设计_Day01