都是基於記憶體的排序演算法,包括插入排序、希爾排序、氣泡排序、快速排序、簡單選擇排序、堆排序、歸併排序
14年在網易blog上寫的,現把它放到這裡。
一,直接插入排序
總體思路:位於表中後面的元素依次與表中前面的元素比較,若比之小,則還需繼續和更前面的元素比較,直至遇到乙個比它大的元素或者比較到第乙個元素(哨兵)了。
①先將第乙個元素視為有序,第二個元素與第乙個元素比較,若比第乙個元素小,則插入到第乙個元素之前。第三個元素依次與第二個元素、第乙個元素比較(前三 個元素有序);第四個元素依次與第三個、第二個、第乙個元素比較,插入到合適位置以形成乙個有序表(即此時前四個元素有序)因此,直接插入排序演算法是逐步 地形成乙個有序序列的。也即在表的前頭形成乙個區域性有序序列。
②不論初始序列如何,總需要 n-1 趟排序,第一趟是第二個元素與第乙個元素比,第二趟是第三個元素與前二個元素比,第三趟是第四個元素與前三個元素比……
③當初始序列有序時,第一趟只需比較一次,第二趟只需比較一次,第三趟也只需比較一次……總共只需比較 n-1 次即可完成排序。當初始序列逆序時,第一趟比較一次,第二趟比較二次,……第 n-1 趟比較 n-1 次。總共比較 n(n-1)/2 次。
④直接插入排列是基於明確的相鄰位置的兩個元素的比較,因此該演算法是穩定的。排序過程的比較次數與待排序列的初始狀態有關。每進行一趟排列並不能唯一地確定下乙個元素的最終位置。
二,希爾排序
①希爾排序演算法也屬於插入排序,它是基於以下因素提出來的:當待排序列不是很大時,用直接插入排序並不怎麼複雜。同時,當初始序列基本有序時,直接插入只需經過少量的比較即可完成排序。
②希爾排序將待排序列按照某個增量分成若干個子串行,分別對每個子串行用直接插入排序演算法時行排序。增量的選取對希爾排序演算法的時間複雜度影響很大。進行 完一趟排序之後,增量就縮小一下。因此,希爾排序也稱縮小增量排序。最後一趟排序時,增量縮小為 1 ,即最後一趟排序相當於直接插入排序。
③希爾排序是不穩定的,因為元素之間的比較是各個子串行中的元素比較。相對於整個待排序列而言,某乙個元素可能會跳躍性地移動。
三,氣泡排序
氣泡排序的思想是:相鄰兩個元素的比較,將小的調到前頭。因此,進行完第一趟排序,就會唯一確定出最大元素,進行完第二趟排序,就會唯一確定出次最大元素……
①由於它是基於相鄰兩個元素之間的比較,因此演算法是穩定的。
②當元素初始序列有序時,在一趟冒泡過程中只需進行 n-1 次比較,沒有進行交換操作即可完成排序。
③當初始序列逆序時,第一趟比較 n-1 次選出最大元素,第二趟比較 n-2 次選出 次最大元素……冒泡法的平均時間複雜度為 o(n^2)。
四,快速排序演算法
基本思路:快排中設定了三個指標,low、high、pivot。low 指向第乙個元素,high 指向最後乙個元素,pivot 指向樞軸元素。首先,從high 指標所指的元素開始,若它比樞軸元素要小,則與樞軸元素交換,否則 high-- 繼續與樞軸元素比較;若 high 所指元素與樞軸元素交換後,則接著將 low 所指元素與樞軸元素比較,若它比樞軸元素小則 low++,否則將 low 所指元素與樞軸元素交換。
①快排的乙個關鍵因素是選好樞軸,它進行一趟排序後,樞軸元素在表中的位置被唯一確定下來,且樞軸元素將待排序列分成兩個子串行,左邊的序列中的元素都比 樞軸元素小,右邊的序列都比樞軸元素大。然後,分別在左右序列中選擇樞軸元素再開始排序,因而,快排中包含了遞迴。
②當待排的元素初始有序時,快排的效能大大地下降。因為此時樞軸劃分的子串行嚴重地不對稱(一般選擇第乙個元素作為樞軸記錄),快排退化為氣泡排序。
③快排是不穩定的,因為在排序過程中,設定了兩個指標 low 和 high 。首先從high 開始自減,尋找第乙個比樞軸小的元素,並將之與樞軸記錄進行交換,這種跳躍式的交換可能會造成元素的相對位置的改變。
④對於快排而言,元素的初始序列與排序的趟數和比較次數是有關的。但是,平均情況下,對於內部排序而言,快排的效能是最好。平均時間複雜度為 o(n^2),空間複雜度為o(logn)。
五,簡單選擇排序
基本思路:第一趟從待排序列中選取最小的元素與放在第乙個位置的元素交換,第二趟選擇次最小的元素與第二個位置的元素交換……這樣,每趟中元素的比較次數與待排序列的初始狀態無關。同時,每進行一趟排序只進行一次交換。
①比較次數及排序趟數與序列的初始狀態無關。
②簡單選擇排序是不穩定的,因為它進行交換時會造成元素的位置跳躍式地變化。
六,堆排序
①在簡單選擇排序中,並沒有充分利用前面比較過程中得出的一些相關資訊。而在堆排序中,則將前面的比較資訊也利用起來。
②討論堆排序,應分成兩步:第一步,將待排元素進行建堆過程。第二步,堆排序過程。
③建堆過程的思想(小頂堆)
將待排序列視為一棵完全二叉樹,畫出該完全二叉樹之後,尋找完全二叉樹中的最後乙個非葉子結點(第 n/2個結點),從該結點開始調整。將該結點的孩子中較小的結點與該結點交換,然後再繼續調整倒數第二個非葉子結點,……注意在這個調整過程中,比如你調 整到了第 i 個非葉子結點了,將第 i 個非葉子結點的值與它的左右孩子結點值比較,將其中較小的值與第 i 個非葉子結點交換。交換了之後,可能造成以第 i 個非葉子結點為根的子樹失去了堆的特徵。此時,應對該子樹繼續進行堆調整,直至其成為乙個堆為止。然後才能再去調整第 i-1 個非葉子結點。
④對於乙個小頂堆而言,堆頂元素一定是序列中元素值最小的元素。因此,直接輸出它,便得到了有序序列中的第乙個元素值。此時,將堆中的最後乙個元素與堆頂 元素置換,並刪除堆中最後乙個元素。此時,破壞了堆的定義,因為需要從堆頂元素起開始向下調整,使之重新變成乙個堆。
⑤對於堆而言,插入乙個元素時,先將之插入在堆對應的完全二叉樹中的最後乙個位置處,然後進行由下而上的堆調整操作。刪除時,總是刪除堆頂元素,並用堆中最後乙個元素置換堆頂元素,並進行由上而下的調整。
⑥堆排序的時間複雜度為 o(logn)。空間複雜度為 o(1)。堆排序是不穩定。進行一趟堆排序可以唯一地確定下來乙個元素的位置(原因有點不懂)。
七,歸併排序
排序過程如下(二路歸併):
①第一趟,將待排序列中的第乙個元素與第二個元素歸結為一組,將第三個元素與第四個元素歸結為一組……將第 n-1 個元素與第 n 個元素歸結為一組,然後將每一組裡面的元素有序排列。
②第二趟,將待排序列中的第
一、二、三、四個元素歸結為一組,第
五、六、七、八個元素歸結為一組……同樣,將每一組裡面的元素有序排序。
…… …… 直至所有的元素有序排列。
③歸併排序的時間複雜度為 o(logn),空間複雜度為 o(n)。但是它是穩定的排序演算法,因為兩兩的歸併,它們之間是基於相鄰元素之間的比較。
各種排序演算法的總結
穩定的排序 1 氣泡排序 工作原理 依次相鄰元素進行比較,將小數放在前面,大數放在後面,每一次掃瞄是將最大的數放在最右邊,每次掃瞄完之後,下次掃瞄的個數減一,知道所有的數都放好位置。即第一次掃瞄 比較第乙個數和第二個數,判斷大小,小數在前,大數在後,接著比較第二個數和第三個數,依次比較,知道最後乙個...
各種排序演算法總結
注 以下所講排序,以公升序排序為例!選擇排序 作者思路 在一組數中,選擇第乙個數標記為最小值,在剩下的數中找比它小的數,若找到則交換兩數,標記新的 最小值 然後繼續往下找,這樣一趟下來就可以找到一組數中第二小的值,第二次以第二個數作為最小值,如此迴圈下去。這是最簡單 最基礎的一種排序演算法。例子 1...
各種排序演算法總結
1 插入排序 void insertsort int a,int n a j 1 key 插入排序是穩定的排序,平均和最壞時間複雜度是o n 2 最好的時間複雜度是o n 對應於全部排好序的情況。2 氣泡排序 void bubblesort int a,intn 氣泡排序是穩定的排序,平均和最壞時間...