1. 程式人生 > >面試前你必須知道的三個排序演算法

面試前你必須知道的三個排序演算法

今天分享的是三種排序演算法,在面試、實際程式設計中經常會碰到和使用到的,我會帶領大家從分析排序演算法技巧上以及程式碼實現上全面理解這一知識點的掌握。

6a552207cb14bdbf2a9a77281300afbe19f1df88

一、如何分析一個「排序演算法」

1. 執行效率

① 最好、最壞、平均時間複雜度

在分析演算法的好壞時,要分別說出最好、最壞、平均時間複雜度的同時,也要說出最好、最壞時間複雜度對應排序的原始資料是什麼樣的。

② 複雜度係數、常數、低階

時間複雜度反應的是資料規模 n 很大的時候的一個增長趨勢,它表示的時候會忽略係數、常數、低階 ,小規模資料除外。

③ 比較次數和移動次數

基於比較的排序演算法,在分析演算法效率時,我們要考慮到元素的比較和元素的移動。

2. 記憶體消耗

演算法的記憶體消耗可以通過空間複雜度來衡量,排序演算法也不例外。我們引用一個名詞叫做「原地排序」,就是指特定空間複雜度是 O(1) 的排序演算法。

3. 穩定性

如果待排序的序列中存在值相等的元素,經過排序之後,相等元素之間原有的先後順序不變,就叫做「穩定排序」。

二、氣泡排序

1、演算法思想

每次冒泡對相鄰的兩個元素進行比較,看是否滿足大小關係,不滿足就進行互換,一次冒泡會讓至少一個元素移動到它應該在的位置。有 n 個數據,需要重複 n 次。

559868f100a88f0c3d2c3974f0a26bf6c02617cf

2、演算法優化

當某次冒泡過程已經沒有資料交換時,說明已經達到完全有序,不用再執行後續的冒泡操作。

3、程式碼實現


1// 氣泡排序,a 表示陣列,n 表示陣列大小 2public void bubbleSort(int[] a, int n) { 3 if (n <= 1) return; 4 5 for (int i = 0; i < n; ++i) { 6 // 提前退出冒泡迴圈的標誌位 7 boolean flag = false; 8 for (int j = 0; j < n - i - 1; ++j) { 9 if (a[j] > a[j+
1]) { // 交換
10 int tmp = a[j]; 11 a[j] = a[j+1]; 12 a[j+1] = tmp; 13 flag = true; // 表示有資料交換 14 } 15 } 16 if (!flag) break; // 沒有資料交換,提前退出 17 } 18}

4、問題思考

①是否為原地排序

冒泡的過程只涉及相鄰資料的交換操作,只需要常量級的臨時空間,所以它的空間複雜度為 O(1),是一個原地排序演算法。

②是否為穩定排序

在氣泡排序中,只有交換才可以改變兩個元素的前後順序。為了保證氣泡排序演算法的穩定性,當有相鄰的兩個元素大小相等的時候,我們不做交換,相同大小的資料在排序前後不會改變順序,所以氣泡排序是穩定的排序演算法。

③最好、最壞以及平均時間複雜度

最好的情況是資料已經排好序,我們只進行一次氣泡排序就可以了,最好時間複雜度為 O(n) 。最壞的情況是,要排序的資料剛好是倒序排列的,我們只進行 n 此冒泡操作,所以最壞的時間複雜度為 O(n²),平均時間複雜度為 O(n²)。

三、插入排序(Insertion Sort)

1、演算法思想

我們將元素分為兩個區間,未排序區間和已排序區間。我們要做的就是在未排序區間取出元素與已排序區間元素進行比較插入到適當位置,以此類推,直到未排序區間元素為空為止(順序為從後向前比較

073d2fe3bee59e8aba3726e4babaf66c09c5c6a2

2、程式碼實現


1// 插入排序,a 表示陣列,n 表示陣列大小(從小到大進行排序) 2public void insertionSort(int[] a, int n) { 3 //如果陣列大小為 1 直接返回 4 if (n <= 1) return; 5 //否則進行插入排序 6 for (int i = 1; i < n; ++i) { 7 int value = a[i]; 8 int j = i - 1; 9 // 查詢插入的位置 10 for (; j >= 0; --j) { 11 if (a[j] > value) { 12 a[j+1] = a[j]; // 資料移動 13 } else { 14 break; 15 } 16 } 17 a[j+1] = value; // 插入資料 18 } 19}

3、問題思考

① 是否為原地排序?

答:插入排序的運算並不需要額外的儲存空間,所以空間複雜度是 O(1),是一個原地排序演算法。

② 是否為穩定排序?

答:在插入排序中,對於值相同的元素,我們會將後邊出現的元素插入到前邊出現的元素的後邊,所以插入排序是穩定排序。

③ 最好、最壞、平均時間複雜度?

答:

最好的情況就是資料元素已經排好序,最好的時間複雜度為 O(1) ,

如果陣列是倒序的,每次插入都相當於在陣列的第一個位置插入新的資料,需要移動大量的資料,最壞的時間複雜度是 O(n²)。

我們在陣列中插入資料的平均時間複雜度為 O(n),對於插入排序來說我們每次就相當於陣列插入一個新的資料,迴圈執行n次插入資料,所以平均時間複雜度為 O(n²)。

四、選擇排序

1、演算法思想

和插入排序有點相似,將在未排序期間尋找到最小的資料,並將其放到已排好區間的元素的尾部。

2、問題思考

① 是否為原地排序

因為,陣列中的兩個元素需要相互交換,需要用一個變數來儲存交換值,選擇排序的空間複雜度為O(1),所以,是一種原地排序演算法。

② 是否為穩定排序

選擇排序每次都要找到剩餘未排序元素的最小值,並和前邊的元素交換位置,這樣破壞了穩定性。所以說,選擇排序是一種不穩定的排序演算法。

③ 最好、最壞以及平均時間複雜度

選擇排序的最好情況就是已經是一組有序資料,最好的時間複雜度為 O(1),最壞的情況就是 O(n²)。平均時間複雜度就是 O(n²)。

3、程式碼實現


1// 選擇排序,a表示陣列,n表示陣列大小 2 public static void selectionSort(int[] a, int n) { 3 if (n <= 1) return; 4 for (int i = 0; i < n; ++i) { 5 // 查詢最小值 6 int minIndex = i; 7 int minValue = a[i]; 8 for (int j = i; j < n; ++j) { 9 if (a[j] < minValue) { 10 minValue = a[j]; 11 for (int i = 0; i < n - 1; ++i) { 12 // 查詢最小值 13 int minIndex = i; 14 for (int j = i + 1; j < n; ++j) { 15 if (a[j] < a[minIndex]) { 16 minIndex = j; 17 } 18 } 19 if (minIndex == i) 20 continue; 21 // 交換 22 int tmp = a[i]; 23 a[i] = a[minIndex]; 24 a[minIndex] = tmp; 25 } 26 }

五、實際應用中為什麼插入排序應用最為廣泛

氣泡排序不管怎麼優化,元素交換的次數是一個固定值,是原始資料的逆序度。插入排序是同樣的,不管怎麼優化,元素移動的次數也等於原始資料的逆序度。

從程式碼實現上來看,氣泡排序的資料交換要比插入排序的資料移動要複雜,氣泡排序需要 3 個賦值操作,而插入排序只需要 1 個。


1氣泡排序中資料的交換操作: 2if (a[j] > a[j+1]) { // 交換 3 int tmp = a[j]; 4 a[j] = a[j+1]; 5 a[j+1] = tmp; 6 flag = true; 7} 8 9插入排序中資料的移動操作: 10if (a[j] > value) {

相關推薦

面試必須知道排序演算法

今天分享的是三種排序演算法,在面試、實際程式設計中經常會碰到和使用到的,我會帶領大家從分析排序演算法技巧上以及程式碼實現上全面理解這一知識點的掌握。 一、如何分析一個「排序演算法」 1. 執行效率 ① 最好、最壞、平均時間複雜度 在分析演算法的好壞時,要分別說出最好、最壞、平均時間複雜度的同時,也

java排序演算法必須會的常見排序演算法

1、排序演算法說明 1、排序的定義 對一序列物件根據某個關鍵字進行排序 2、術語說明 穩定:如果a原本在b前面,而a=b,排序之後a仍然在b的前面; 不穩定:如果a原本在b的前面,而a=b,排序之後a可能會出現在b的後面; 內排序:所有排序操作都在記憶體中完成;

必須知道的10Python第

1. BeautifulSoup Beautiful Soup是一個可以從HTML,XML進行提取檔案的Python庫,日常我們使用爬蟲進行資料抓取回來之後,往往需要進行資料解析。 使用它能讓你開心愉快提取裡面的爬回來的資料。 本人對於Python學習建立了一個小小的學習圈子,為

想要成功應聘Java高階開發工程師,8必須知道面試考綱

點選上方“程式設計師大咖”,選擇“置頂公眾號”關鍵時刻,第一時間送達!市面上,有很多Java的學

HTML5必須知道的28新特性

html5你必須知道的28個新特性HTML5有很多的新功能.新代碼.非常不錯.現在總結一下.僅供參考1. 新的Doctype盡管使用<!DOCTYPE html>,即使瀏覽器不懂這句話也會按照標準模式去渲染2. Figure元素 用<figure>和<figcaption>

關於建站必須知道的六常識

fun 分享圖片 選擇 不能 軟件 索引 轉化率 網民 aid 你以為搭建好網站就可以高枕無憂了嗎?其實不是。建站就和養花是一樣的模式,是需要精心地去維護,才能夠得到想要的效果。 如果建設好網站之後不管不顧,那麽這個網站就是一個死站,產生不了一絲一毫的效益,就變得毫無存在的

[必須知道的.NET]第十三回,深入.NET 4.0之,Lazy<T>點滴

釋出日期:2009.10.29 作者:Anytao © 2009 Anytao.com ,Anytao原創作品,轉貼請註明作者和出處。   物件的建立方式,始終代表了軟體工業的生產力方向,代表了先進軟體技術發展的方向,也代表了廣大程式開發者的集體

學習web前端必須知道這些,讓少走很多彎路

IT行業是所有行業中能力要求最高的,相應的薪水待遇也是讓人羨慕。想要勝任一份高薪的工作並不那麼容易,新手甚至0基礎的小白想要踏入這一行業需要了解些什麼呢?   在之前的幾年IT行業一度超越了掙錢最多的金融行業,因為如果說在中國所有行業中,給人打工的話,做軟體開發這塊應該是工資提升的最顯著最快的,

必須知道的8大資料結構,程式設計師面試

有些面試題會明確提及某種資料結構,例如,“給定一個二叉樹。”而另一些則隱含在面試題中,例如,“我們希望記錄每個作者相關的書籍數量。” 什麼是資料結構? 簡單地說,資料結構是以某種特定的佈局方式儲存資料的容器。這種“佈局方式”決定了資料結構對於某些操作是高效的,而對於其他操作則是低效的

關於JAVA必須知道的那些事():繼承和訪問修飾符

今天乘著還有一些時間,把上次拖欠的面向物件程式設計三大特性中遺留的繼承和多型給簡單說明一下。這一部分還是非常重要的,需要仔細思考。 繼承 繼承:它是一種類與類之間的關係,通過使用已存在的類作為基礎來建立新類。其中已存在的類稱為父類(或基類); 建立的新類稱為子類(或派生類)。簡單的就是子類繼

除了Hadoop,其他6必須知道的熱門大資料技術

      你知道新的市場領導者和曾經的領導者之間的關鍵區別是什麼嗎? 那就是“資料管理”。任何無法處理資料並將其投入使用的企業,很可能會讓位給那些能夠更好處理資料的。 事實上,大資料和其流動性的力量能促使企業發展。 大資料是大量資料的術語

除了Hadoop,還有6必須知道的熱門大資料技術

你知道新的市場領導者和曾經的領導者之間的關鍵區別是什麼嗎?   那就是“資料管理”。任何無法處理資料並將其投入使用的企業,很可能會讓位給那些能夠更好處理資料的。   事實上,大資料和其流動性的力量能促使企業發展。   大資料是大量資料的術語。由於

如何寫好程式碼?必須知道的幾原則

簡介 編輯技術裡,靈魂之上的東西某過於設計模式。設計模式之上的東西其實就是純粹的準則。基於準則之上的程式碼才有靈魂可言,經得起推敲,也經得起考驗。 單一職責原則 定義 就一個類而言,應當僅有一個引起它變化的原因。 說明 所謂單一職責就是一個類設計之初它所在職責就

ES5和ES6那些必須知道的事兒()

ES5和ES6那些你必須知道的事兒 ES6新增的東西 一、塊級作用域:關鍵字let,常量const 二、物件字面量屬性賦值簡寫 var name = “我是name”; var age = 18; var obj = { name, age } //此處的物件的k

Scrum Master 面試題 – 必須知道的22Scrum基礎知識

以下的22個問題基本上涵蓋了Scrum所涉及的內容,如果你能夠正確回答出所有問題,那麼你已經具備了作為一名Scrum Master的基本素質;當然,作為一名合格的Scrum Master,更重要的是你的經驗,因為Scrum Master更多的需要和人打交道,很多實際問題的處理方式是必須在實踐中才能體會的

Python必須知道的十

Python是優雅的,使用這些庫可以使你的程式碼更簡潔,並保持永續性。歡迎各位補充,並提出意見! Docopt。拋棄optparse和argparse吧,使用docstrings來構建優雅的,可讀性強的,並且複雜(如果你需要的話)的命令列介面。IMO*2013

HTTP 協議中必須知道種資料格式

實習中的一個主要工作就是分析 HTTP 中的協議,自己也用 Python 寫過正則表示式對 HTTP 請求和響應的內容進行匹配,然後把關鍵欄位抽離出來放到一個字典中以備使用(可以稍微改造一下就是一個爬蟲工具)。 HTTP 協議中的很多坑,自己都遇到過,我就針對自己遇到的

【科普】必須知道的10SaaS相關的概念

今天我們就來為大家科普一下SaaS行業的幾大基本概念。 CRM 目前看來,CRM在SaaS行業佔有舉足輕重的地位,而根據IDC預測,到2018年,全球CRM SaaS軟體的市場規模將達198億美元,成為第一大SaaS軟體品類。那麼CRM究竟是什麼? CRM是英文

雲端計算之必須知道的幾會議和雜誌

雲端計算現在被大家炒的熱火朝天,那麼很多人也想更多瞭解雲端計算。那麼我就給大家介紹幾個雜誌和網站。 IEEE International Conference on Cloud Computingh

翻譯-必須知道的28HTML5特徵、竅門和技術

這篇文章釋出於 2010年08月27日,星期五,21:50,歸類於 外文翻譯。 閱讀 108784 次, 今日 11 次 //zxx:以下為翻譯全文,本著語言生動和本土化之原則,內容有編輯 注意:每週有那麼幾次,此列表會更新一些新的竅門,最終,本文會成為超級有用