標(biāo)題:
js算法之最常用的排序
[打印本頁]
作者:
51hei小林
時(shí)間:
2016-9-25 11:38
標(biāo)題:
js算法之最常用的排序
引入
大學(xué)學(xué)習(xí)計(jì)算機(jī)語言的那幾年,從c語言,到c++,再到數(shù)據(jù)結(jié)構(gòu)JAVA..讓我印象最深刻的還是最開始老師講冒泡算法的時(shí)候,直到現(xiàn)在大四快畢業(yè)了我才漸漸通竅了。剛學(xué)前端的時(shí)候以為前端就是做出好看很炫的頁面就行了,后來才漸漸懂得前端不只是頁面仔。一次美團(tuán)面試,面試官說他們要的不僅是前端,他們要的是“工程師”,從面試開始到結(jié)束問都是算法,頓時(shí)把我給打擊了。二叉樹、基本算法還有時(shí)間復(fù)雜度都是很重要的東西,不僅體現(xiàn)了一個(gè)前端的學(xué)習(xí)深度,還體現(xiàn)了一名計(jì)算機(jī)學(xué)生的專業(yè)水平。所以,為了查缺補(bǔ)漏,我決定開始研究一下程序猿最愛提的算法,今天聊聊最常用的排序算法。魷魚看過很多資料覺得都太專業(yè)化了,根本看不懂,所以以下我都盡量用能讓自己(別人)看懂的介紹來描述啦~
常用排序算法
冒泡排序(Bubble sort)
大白話介紹:比較相鄰的兩個(gè)數(shù),如果后面的比前面的小,把小的放在前面。
時(shí)間復(fù)雜度: O(n2)
動畫演示:冒泡排序
實(shí)際代碼:
方法一:function bubbleSort(arr){
for(var i=0;i<arr.length-1;i++){
for(var j=0;j<arr.length-1;j++){
if(arr[j+1]<arr[j]){
temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}//對比arr中的第j+1項(xiàng)和第j項(xiàng),如果第j+1項(xiàng)小于第j項(xiàng),就把第j+1項(xiàng)和第j項(xiàng)調(diào)換位置。如果沒達(dá)到最終的順序(從小到大),就繼續(xù)找,繼續(xù)換,直到達(dá)到最終效果但是上面的方法并不完美,如果數(shù)組已經(jīng)是有序了,就沒必要再比較了,所以下面有一種優(yōu)化冒泡排序算法:
優(yōu)化冒泡排序算法
方法二(優(yōu)化算法):function bubbleSort(arr){
var flag = false; // 定義一個(gè)變量為false,未交換位置
for(var i=0;i<arr.length-1;i++){
for(var j=0;j<arr.length-1;j++){
if(arr[j+1]<arr[j]){
temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
flag = true; //true,已交換位置
}
}
if(flag){
flag = false; //如果交換了位置,將flag重新設(shè)為false
}else{
break; //如果未交換,則跳出循環(huán)
}
}
return arr;
}或者寫成這樣~function bubbleSort(arr){
var flag;
for(var i=0;i<arr.length-1;i++){
flag =false;
for(var j=0;j<arr.length-1;j++){
if(arr[j+1]<arr[j]){
temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
flag = true;
}
}
if(!flag){
return arr;
}
}
return arr;
}
選擇排序(selection Sort)
大白話介紹:在亂序的數(shù)組中選擇最小的值,然后和每次循環(huán)后的數(shù)組的第一位進(jìn)行交換
時(shí)間復(fù)雜度:O(n2)
動畫演示:選擇排序
實(shí)際代碼:
var arr=[5,3,2,4,1,0];function findMin(arr,first){
var minindex = first; //定義最小下標(biāo)
var minNum = arr[first]; //定義數(shù)組中的最小值
for(var i=first+1;i<arr.length;i++){ //循環(huán)找到最小值和最小下標(biāo)
if(arr[i]<minNum){
minNum = arr[i];
minindex = i;
}
}
return minindex;//返回最小值下標(biāo) 一共查找了六次,最小值下標(biāo)分別為 :5,4,2,4,4,5
}
function selectionSort(arr){
for(var i=0;i<arr.length;i++){
var min =var temp = arr[min];
arr[min] = arr[i]; //eg.第一次循環(huán) :將最小值5和arr[0]進(jìn)行交換
arr[i] = temp; // 剩下幾次同第一次
}
return arr;
}
document.write(selectionSort(arr)); //0,1,2,3,4,5, 排序過程:(自己畫的一個(gè)粗糙的框框表嫌棄)
歸并排序(mergeSort)
大白話介紹: 把一個(gè)數(shù)組分為兩個(gè)數(shù)組,左邊排好序,右邊排好序,然后合并到一起排序
專業(yè)性介紹: 歸并排序是分治法的典型實(shí)例,指的是將兩個(gè)已經(jīng)排序的序列合并成一個(gè)序列的操作
時(shí)間復(fù)雜度: O(nlogn)
動畫演示:歸并排序
實(shí)際代碼:
var arr=[-11,17,12,19,0,-222];
function mergeSort(arr,s,e){
if(s>e){ //起始位置大于終點(diǎn)位置,返回空數(shù)組
return [];
}else if(s==e){
return [arr[s]]; //起始位置等于終點(diǎn)位置,說明數(shù)組里只有一個(gè)數(shù)字,返回只含一個(gè)數(shù)字的數(shù)組
}
var mIndex = Math.floor((s+e)/2); //中間位置的Index
var arrL = mergeSort(arr,s,mIndex); //將左邊的數(shù)組排序
var arrR = mergeSort(arr,mIndex+1,e); //將右邊的數(shù)組排序
var resultArr = []; //結(jié)果數(shù)組
while(arrL.length>0 || arrR.length>0){ //當(dāng)左右兩個(gè)數(shù)組都不為空時(shí)
if(arrL[0]<arrR[0]){
resultArr.push(arrL.shift());
}else{
resultArr.push(arrR.shift());
}
if(arrL.length==0){ //當(dāng)左邊的數(shù)組為空時(shí)
resultArr = resultArr.concat(arrR);
break;
}else if(arrR.length==0){
resultArr = resultArr.concat(arrL);
break;
}
}
return resultArr;
}
document.write(mergeSort(arr,0,arr.length-1)); 排序過程:
快速排序(quickSort)
大白話介紹:引用阮一峰老師的一句話,感覺是極好理解的~(我的目標(biāo)也是成為像阮一峰老師這樣的)
(1)在數(shù)據(jù)集之中,選擇一個(gè)元素作為"基準(zhǔn)"(pivot)。
。2)所有小于"基準(zhǔn)"的元素,都移到"基準(zhǔn)"的左邊;所有大于"基準(zhǔn)"的元素,都移到"基準(zhǔn)"的右邊。
(3)對"基準(zhǔn)"左邊和右邊的兩個(gè)子集,不斷重復(fù)第一步和第二步,直到所有子集只剩下一個(gè)元素為止。 實(shí)際代碼:
var arr=[77,-33,22,32,0,2,11];
function quickSort(arr){
if(arr.length<=1){ //如果數(shù)組中只有一位數(shù),返回?cái)?shù)組
return arr;
}
var mNumIndex = Math.floor(arr.length/2); //取基準(zhǔn)值的下標(biāo)
var mNum = arr.splice([mNumIndex],1)[0]; //取基準(zhǔn)值
var left = []; //左邊數(shù)組
var right = []; //右邊數(shù)組
for(var i=0;i<arr.length;i++){
if(arr[i]<mNum){ //如果數(shù)組小于基準(zhǔn)值,放在左邊數(shù)組
left.push(arr[i]);
}else{ ///否則
right.push(arr[i]);
}
}
return quickSort(left).concat([mNum],quickSort(right)); //返回左邊數(shù)組+基準(zhǔn)值+右邊數(shù)組
}
document.write(quickSort(arr)); 排序過程:
復(fù)制代碼
以上就是一些常見的排序了,但是還有很多常見的排序沒有提到~~ 后期還會寫一個(gè)常用排序二~敬請期待噢 ~希望我學(xué)到的東西也能幫助到大家~有說錯(cuò)的地方歡迎批評指正~
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1