1. 程式人生 > >白話經典算法系列之四 直接選擇排序及交換二個數據的正確實現

白話經典算法系列之四 直接選擇排序及交換二個數據的正確實現

直接選擇排序和直接插入排序類似,都將資料分為有序區和無序區,所不同的是直接播放排序是將無序區的第一個元素直接插入到有序區以形成一個更大的有序區,而直接選擇排序是從無序區選一個最小的元素直接放到有序區的最後。

設陣列為a[0…n-1]。

1.      初始時,陣列全為無序區為a[0..n-1]。令i=0

2.      在無序區a[i…n-1]中選取一個最小的元素,將其與a[i]交換。交換之後a[0…i]就形成了一個有序區。

3.      i++並重復第二步直到i==n-1。排序完成。

直接選擇排序無疑是最容易實現的,下面給出程式碼:

  1. void Selectsort(int a[], int n)
  2. {
  3. int i, j, nMinIndex;
  4. for (i = 0; i < n; i++)
  5. {
  6. nMinIndex = i; //找最小元素的位置
  7. for (j = i + 1; j < n; j++)
  8. if (a[j] < a[nMinIndex])
  9. nMinIndex = j;
  10. Swap(a[i], a[nMinIndex]); //將這個元素放到無序區的開頭
  11. }
  12. }

在這裡,要特別提醒各位注意下Swap()的實現,建議用:

  1. inline void Swap(int &a, int &b)
  2. {
  3. int c = a;
  4. a = b;
  5. b = c;
  6. }

筆試面試時考不用中間資料交換二個數,很多人給出了

  1. inline void Swap1(int &a, int &b)
  2. {
  3. a ^= b;
  4. b ^= a;
  5. a ^= b;
  6. }

在網上搜索下,也可以找到許多這樣的寫法。不過這樣寫存在一個隱患,如果a, b指向的是同一個數,那麼呼叫Swap1()函式會使這個數為0。如:

  1. int i = 6;
  2. Swap2(i, i);
  3. printf("%d %d\n", i);

當然誰都不會在程式中這樣的寫程式碼,但回到我們的Selectsort(),如果a[0]就是最小的數,那麼在交換時,將會出現將a[0]置0的情況,這種錯誤相信除錯起來也很難發現吧,因此建議大家將交換二數的函式寫成:

  1. inline void Swap
    (int &a, int &b)
  2. {
  3. int c = a;
  4. a = b;
  5. b = c;
  6. }

或者在Swap1()中加個判斷,如果二個數據相等就不用交換了:

  1. inline void Swap1(int &a, int &b)
  2. {
  3. if (a != b)
  4. {
  5. a ^= b;
  6. b ^= a;
  7. a ^= b;
  8. }
  9. }

相關推薦

白話經典系列 直接選擇排序交換個數正確實現

直接選擇排序和直接插入排序類似,都將資料分為有序區和無序區,所不同的是直接播放排序是將無序區的第一個元素直接插入到有序區以形成一個更大的有序區,而直接選擇排序是從無序區選一個最小的元素直接放到有序區的最後。 設陣列為a[0…n-1]。 1.      初始

白話經典系列三 希爾排序實現

希爾排序的實質就是分組插入排序,該方法又稱縮小增量排序,因DL.Shell於1959年提出而得名。   該方法的基本思想是:先將整個待排元素序列分割成若干個子序列(由相隔某個“增量”的元素組成的)分別進行直接插入排序,然後依次縮減增量再進行排序,待整個序列中的元素基本有序(增量足夠小)

白話經典系列九 從歸併排序到數列的逆序數對(微軟筆試題)

首先來看看原題   微軟2010年筆試題 在一個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為一個逆序數對。一個排列中逆序的總數就稱為這個排列的逆序數。如{2,4,3,1}中,2和1,4和3,4和1,3和1是逆序數對,因此整個陣列的逆序數對個數為

白話經典系列六】 快速排序 快速搞定

快速排序由於排序效率在同為O(N*logN)的幾種排序方法中效率較高,因此經常被採用,再加上快速排序思想----分治法也確實實用,因此很多軟體公司的筆試面試,包括像騰訊,微軟等知名IT公司都喜歡考這個,還有大大小的程式方面的考試如軟考,考研中也常常出現快速排序的身影。 總

白話經典系列十一】一道有趣的GOOGLE面試題 --【解法2】

                上一篇《白話經典算法系列之十一道有趣的GOOGLE面試題》中對一道有趣的GOOGLE面試題進行了詳細的講解,使用了類似於基數排序的做法在O(N)的時間複雜度和O(1)的空間複雜度完成了題目的要求,文章發表後,網友fengchaokobe在評論中給出了另一種解法,見下圖。文字版:

白話經典系列六 快速排序 快速搞定

                 快速排序由於排序效率在同為O(N*logN)的幾種排序方法中效率較高,因此經常被採用,再加上快速排序思想----分治法也確實實用,因此很多軟體公司的筆試面試,包括像騰訊,微軟等知名IT公司都喜歡考這個,還有大大小的程式方面的考試如軟考,考研中也常常出現快速排序的身影。總的說來

白話經典系列七 堆與堆排序

 堆排序與快速排序,歸併排序一樣都是時間複雜度為O(N*logN)的幾種常見排序方法。學習堆排序前,先講解下什麼是資料結構中的二叉堆。二叉堆的定義二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足二個特

白話經典系列五 歸併排序實現(講的真好)

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。 首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第一個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再

白話經典系列五 歸併排序實現

 歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列

【轉】白話經典系列六 快速排序 快速搞定

轉自:http://blog.csdn.net/morewindows/article/details/6684558 快速排序由於排序效率在同為O(N*logN)的幾種排序方法中效率較高,因此經常被採用,再加上快速排序思想----分治法也確實實用,因此很多軟體公司的筆試面試,包括像騰訊,微軟等知名IT公

白話經典系列之一 氣泡排序的三種實現

                 氣泡排序是非常容易理解和實現,,以從小到大排序舉例:設陣列長度為N。1.比較相鄰的前後二個數據,如果前面資料大於後面的資料,就將二個數據交換。2.這樣對陣列的第0個數據到N-1個數據進行一次遍歷後,最大的一個數據就“沉”到陣列第N-1個位置。3.N=N-1,如果N不為0就重複

經典系列不死神兔

Fibonacci為1200年代的歐洲數學家,在他的著作中曾經提到:「若有一隻免子每個月生一隻小免子,一個月後小免子也開始生產。起初只有一隻免子,一個月後就有兩隻免子,二個月後有三隻免子,三個月後有五隻免子(小免子投入生產)......。 這就是著名的不死神兔問題,即Fib

基礎系列排序演算法-3. 直接插入排序 並用其解決HDU 1106 排序

      我們之前已經學習了氣泡排序和二分查詢兩種基本演算法,本篇文章我們將一起學習下一個基礎演算法——直接插入排序演算法。  直接插入排序      直接插入排序,從這個名字來看,是不是讓你想到了什麼場景?!對了,就是打撲克牌的場景,我們每摸一張牌,是不是按照一定的次

排序系列直接插入排序

直接插入排序 1 基本原理 1 核心思想:插入排序通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃描,找到相應位置並插入 ,如此重複,直至完成序列排序。 2 演算法分析:

系列:狼、羊、菜和農夫過河問題

題目描述:農夫需要把狼、羊、菜和自己運到河對岸去,只有農夫能夠划船,而且船比較小,除農夫之外每次只能運一種東西,還有一個棘手問題,就是如果沒有農夫看著,羊會偷吃菜,狼會吃羊。請考慮一種方法,讓農夫能夠安全地安排這些東西和他自己過河。        這個題目考察人的快速邏輯運算

系列十八:用天文方法計算節氣(上)

        二十四節氣在中國古代曆法中扮演著非常重要的角色,本文將介紹二十四節氣的基本知識,以及如何使用VSOP82/87行星執行理論計算二十四節氣發生的準確時間。        中國古代曆法都是以月亮執行規律為主,嚴格按照朔望月長度定義月,但是由於朔望月長度和地球迴歸年

結構與系列研究——數組和廣義表

cout stdlib.h idt fcc 地址 space stream emp style 稀疏矩陣的十字鏈表實現和轉置 一、數組和廣義表的定義 數組的定義1:一個 N 維數組是受 N 組線性關系約束的線性表。 二維數組的邏輯結構可形式地描述

系列枚舉】生理周期

pac cin 輸出 peak 給定 cout 指定 eno d+ 題目     人有體力、情商、智商的高峰日子,它們分別每隔 23天、28天和33天出現一次。對於每個人,我們想 知道何時三個高峰落在同一天。給定三個高峰出現 的日子p,e和i(不一定是第一次高峰出

系列<快速排序>

quicksort n) param arr [] array code quick 成長 快速排序: /** * 快速排序 * 最好情況下:每趟把原序列分成兩個長度幾乎相等的子序列 * 最差情況下:每趟把原序列分成長度相差很大的兩個子序列

圖解排序(一)3種簡單排序(選擇,冒泡,直接插入)

容易 ble 通過 元素移動 shells 過程 影響 項目 lec 排序是數據處理中十分常見且核心的操作,雖說實際項目開發中很小幾率會需要我們手動實現,畢竟每種語言的類庫中都有n多種關於排序算法的實現。但是了解這些精妙的思想對我們還是大有裨益的。本文簡單溫習下最基礎的三類