摘要:選擇排序就這么簡單從上一篇已經(jīng)講解了冒泡排序了,本章主要講解的是選擇排序,希望大家看完能夠理解并手寫出選擇排序的代碼,然后就通過面試了如果我寫得有錯誤的地方也請大家在評論下指出。
選擇排序就這么簡單
從上一篇已經(jīng)講解了冒泡排序了,本章主要講解的是選擇排序,希望大家看完能夠理解并手寫出選擇排序的代碼,然后就通過面試了!如果我寫得有錯誤的地方也請大家在評論下指出。
選擇排序介紹和穩(wěn)定性說明來源百度百科:
選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理是每一次從待排序的數(shù)據(jù)元素中選出最小(或最大)的一個元素,存放在序列的起始(末尾)位置,直到全部待排序的數(shù)據(jù)元素排完。選擇排序是不穩(wěn)定的排序方法(比如序列[5, 5, 3]第一次就將第一個[5]與[3]交換,導(dǎo)致第一個5挪動到第二個5后面)。
上面提到了選擇排序是不穩(wěn)定的排序方法,那我們的冒泡排序是不是穩(wěn)定的排序方法呢?穩(wěn)定的意思指的是什么呢?
判斷某排序算法是否穩(wěn)定,我們可以簡單理解成:排序前2個相等的數(shù)其在序列的前后位置順序和排序后它們兩個的前后位置順序相同
如果相同,則是穩(wěn)定的排序方法。
如果不相同,則是不穩(wěn)定的排序方法
如果排序前的數(shù)組是[3,3,1],假定我們使用選擇排序的話,那第一趟排序后結(jié)果就是[1,3,3]。這個數(shù)組有兩個相同的值,它倆在array[0]和array[1],結(jié)果經(jīng)過排序,array[0]的跑到了array[2]上了。
那么這就導(dǎo)致:2個相等的數(shù)其在序列的前后位置順序和排序后它們兩個的前后位置順序不相同,因此,我們就說它是不穩(wěn)定的
再回到上面的問題,上一篇說講的冒泡排序是穩(wěn)定的,主要原因是:倆倆比較的時候,沒有對相等的數(shù)據(jù)進(jìn)行交換(因為沒必要)。因此它不存在2個相等的數(shù)其在序列的前后位置順序和排序后它們兩個的前后位置順序不相同。
那么穩(wěn)定排序的好處是什么?
參考知乎回答@獨行俠的回答:
如果我們只對一串?dāng)?shù)字排序,那么穩(wěn)定與否確實不重要,因為一串?dāng)?shù)字的屬性是單一的,就是數(shù)字值的大小。但是排序的元素往往不只有一個屬性,例如我們對一群人按年齡排序,但是人除了年齡屬性還有身高體重屬性,在年齡相同時如果不想破壞原先身高體重的次序,就必須用穩(wěn)定排序算法.
很清晰的指出,只有當(dāng)在“二次”排序時不想破壞原先次序,穩(wěn)定性才有意義
參考資料:
https://www.zhihu.com/question/46809714/answer/281361290
http://tieba.baidu.com/p/872860935
http://www.cnblogs.com/codingmylife/archive/2012/10/21/2732980.html
一、第一趟排序它的工作原理是每一次從待排序的數(shù)據(jù)元素中選出最小(或最大)的一個元素,存放在序列的起始(末尾)位置,直到全部待排序的數(shù)據(jù)元素排完
首先,我們創(chuàng)建數(shù)組,找到它最大的值(這就很簡單了):
int[] arrays = {2, 3, 1, 4, 3, 5, 1, 6, 1, 2, 3, 7, 2, 3}; //假定max是最大的 int max = 0; for (int i = 0; i < arrays.length; i++) { if (arrays[i] > max) { max = arrays[i]; } }
隨后這個最大的數(shù)和數(shù)組末尾的數(shù)進(jìn)行交換:
//使用臨時變量,讓兩個數(shù)互換 int temp; temp = arrays[11]; arrays[11] = arrays[13]; arrays[13] = temp;
那么經(jīng)過第一趟排序,我們的最大值已經(jīng)到了數(shù)組的末尾了。
二、第二趟排序再次從數(shù)組獲取最大的數(shù)(除了已經(jīng)排好的那個):
int max2 = 0; for (int i = 0; i < (arrays.length - 1); i++) { if (arrays[i] > max2) { max2 = arrays[i]; } } System.out.println(max2);
再將獲取到的最大值與數(shù)組倒數(shù)第二位交換:
temp = arrays[7]; arrays[7] = arrays[12]; arrays[12] = temp;
經(jīng)過第二次排序,已經(jīng)能夠?qū)?shù)組最大兩個數(shù)進(jìn)行排序了
三、代碼簡化從前兩趟排序其實我們就可以摸出規(guī)律了:
一個數(shù)組是需要n-1趟排序的(因為直到剩下一個元素時,才不需要找最大值)
每交換1次,再次找最大值時就將范圍縮小1
查詢當(dāng)前趟數(shù)最大值實際上不用知道最大值是多少(上面我查出最大值,還要我手動數(shù)它的角標(biāo)),知道它的數(shù)組角標(biāo)即可,交換也是根據(jù)角標(biāo)來進(jìn)行交換
第一趟:遍歷數(shù)組14個數(shù),獲取最大值,將最大值放到數(shù)組的末尾[13]
第二趟:遍歷數(shù)組13個數(shù),獲取最大值,將最大值放到數(shù)組倒數(shù)第二位[12]
....
數(shù)組有14個數(shù),需要13趟排序。
//記錄當(dāng)前趟數(shù)的最大值的角標(biāo) int pos ; //交換的變量 int temp; //外層循環(huán)控制需要排序的趟數(shù) for (int i = 0; i < arrays.length - 1; i++) { //新的趟數(shù)、將角標(biāo)重新賦值為0 pos = 0; //內(nèi)層循環(huán)控制遍歷數(shù)組的個數(shù)并得到最大數(shù)的角標(biāo) for (int j = 0; j < arrays.length - i; j++) { if (arrays[j] > arrays[pos]) { pos = j; } } //交換 temp = arrays[pos]; arrays[pos] = arrays[arrays.length - 1 - i]; arrays[arrays.length - 1 - i] = temp; } System.out.println("公眾號Java3y" + arrays);四、選擇排序優(yōu)化
博主暫未想到比較好的優(yōu)化方法,如果看到這篇文章的同學(xué)知道有更好的優(yōu)化方法或者代碼能夠?qū)懙酶玫牡胤?,歡迎在評論下留言哦!
查到的這篇選擇排序優(yōu)化方法,感覺就把選擇排序變了個味,大家也可以去看看:
他是同時獲取最大值和最小值,然后分別插入數(shù)組的首部和尾部(這跟選擇排序的原理好像差了點,我也不知道算不算)
http://www.cnblogs.com/TangMoon/p/7552921.html
五、擴(kuò)展閱讀C語言實現(xiàn)
int findMaxPos ( int arr[], int n) { int max = arr[0]; int pos = 0; for (int i = 1; i < n; i++) { if (arr[i] > max) { max = arr[i]; pos = i; } } return pos; } void selectionSort ( int arr[], int n) { while (n > 1) { int pos = findMaxPos(arr, n); int temp = arr[pos]; arr[pos] = arr[n - 1]; arr[n - 1] = temp; n--;// } } int main () { int arr[] = {5, 32, 7, 89, 2, 3, 4, 8, 9}; selectionSort(arr, 9); for (int i = 0; i < 9; i++) cout << arr[i] << endl; }
如果文章有錯的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號:Java3y
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68850.html
摘要:不斷執(zhí)行這個操作代碼實現(xiàn)快速排序用遞歸比較好寫如果不太熟悉遞歸的同學(xué)可到遞歸就這么簡單。 前言 大概花了一周的時間把八大基礎(chǔ)排序過了一遍,這篇博文主要是用來回顧一下八大基礎(chǔ)排序的要點和一些總結(jié)~ 回顧: 冒泡排序就這么簡單 選擇排序就這么簡單 插入排序就這么簡單 快速排序就這么簡單 歸并排序就這么簡單 堆排序就這么簡單 希爾排序就這么簡單 基數(shù)排序就這么簡單 總的來說:快速排序是用...
摘要:前言由于寫的文章已經(jīng)是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時間才會更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號:Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡單 注解就這么簡單 Druid數(shù)據(jù)庫連接池...
閱讀 857·2023-04-25 23:59
閱讀 3758·2021-10-08 10:04
閱讀 1692·2019-08-30 14:05
閱讀 1027·2019-08-30 13:58
閱讀 500·2019-08-29 18:41
閱讀 1135·2019-08-29 17:15
閱讀 2328·2019-08-29 14:13
閱讀 2753·2019-08-29 13:27