JS氣泡排序的6種寫法

疾風天荒發表於2019-03-08
天下英雄出我輩,一入江湖歲月催。鴻圖霸業談笑間,不勝人生一場醉。      
武當山上,一年一度的試道大會又開始了...   
眾武當弟子摩拳擦掌都想在此次試道大會上一展風采...    
張三丰臨終前曾留下一句話:試道大會採用氣泡排序....    
冒泡思想:每冒泡一輪(外層for迴圈控制),選出這一輪中最大的數(內層for迴圈依次兩兩比較逐步移到最後...)
一共進行arr.length-1輪 (2個比一輪、3個比兩輪、悟不出來自己收拾行李快快下山吧,我武當派沒有你這樣的弟子!)
每輪比較arr.length-1次?(因為每一輪冒泡得到的最大值已經得道成仙無需再比 所以每輪比較arr.length-1-i次)
複製程式碼

靈魂版1(實力對決之一個都不能少)

由兩位德高望重的裁判主持
主裁判(外層for迴圈)負責輪數,副裁判(內層for迴圈)在主裁判的指導下負責每一場比武...
複製程式碼
	bubbleSortSoul1 = (arr = []) => {
		let count = 0;
		// i為輪數(因i從0開始 即i<arr.length-1)
		for (let i = 0; i < arr.length - 1; i++) {
			count++;
			// 第i輪僅需比較length-1-i次
			for (let j = 0; j < arr.length - 1 - i; j++) {
				// 這裡能不能寫成arr[j-1]>arr[j]? 如果有這種特殊癖好 那麼j就從1開始吧,然後j<arr.length-i
				if (arr[j] > arr[j + 1]) {
					let temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
		}
		console.log(`bubbleSortSoul1排序完成用了${count}輪`);
		return arr;
	}
複製程式碼

靈魂版2(實力對決之換湯不換藥)

副裁判突發奇想,竟悟出--心法,每輪比武不再需要主裁判詳細指導(不用-i)
複製程式碼
	bubbleSortSoul2 = (arr = []) => {
		let length = arr.length - 1;
		let count = 0;
		for (let i = 0; i < arr.length - 1; i++) {
			count++;
			// 這裡的length第一輪==arr.length-1-0跟上一版一樣
			for (let j = 0; j < length; j++) {
				if (arr[j] > arr[j + 1]) {
					let temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
			// 每一次內層for迴圈比較完成-1 跟前面的-i一樣 換湯不換藥
			length--;
		}
		console.log(`bubbleSortSoul2排序完成用了${count}輪`);
		return arr;
	}
複製程式碼

靈魂版3(實力對決之副裁判獨擔重任)

主裁判臨時有事請假,大會當頭,副裁判迫於壓力終悟出冒泡心經,大會依然有序進行...
複製程式碼
	bubbleSortSoul3 = (arr = []) => {
		let length = arr.length - 1;
		let count = 0;
		// 單層for迴圈
		for (let j = 0; j < length; j++) {
			if (arr[j] > arr[j + 1]) {
				let temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
			// 在迴圈到最大值時候重置j(j=-1到上面j++重置為0)這樣可以省了外層for迴圈
			// 某弟子問:兄dei 這樣也行?靠譜不?師傅知道你在瞎搞不?
			// 副裁判:好好比武別廢話!冒泡心經!汝輩豈知?
			if (j == length - 1) {
				j = -1;
				length--;
				count++;
			}
		}
		console.log(`bubbleSortSoul3排序完成用了${count}輪`);
		return arr;
	}
複製程式碼

沒有靈魂版1(flag心法?比武可能提前結束)

師父得知副裁判在主裁判不在的情況下成功舉行了一場大會,頗為高興,決定傳一套flag心法給副裁判
此次大會由主裁判弟弟while擔任,弟弟畢竟是弟弟,知道的太少了,只能聽從安排
副裁判對弟弟說:這樣吧,等會比武我微信給你發true你就喊開始,發false你就喊結束,are you OK? 弟弟表示很OK
內幕:部分弟子比武期間被安排得明明白白?比武提前結束...
複製程式碼
	bubbleSortNoSoul1 = (arr = []) => {
		let [length, flag, count] = [arr.length - 1, true, 0];
		// 這裡用while執行輪數 (也可以用for)
		while (flag) {
			count++;
			// flag心法第一章:他強由他強 清風拂山崗 他橫由他橫 明月照大江
			// 副裁判準備馬上微信給弟弟發false想要結束比武 剛打好沒發出去 下面的弟子開始躁動了 幹哈呢 比不比了??
			// 好在副裁判有慧根 立即悟出原理(此次比完沒有交換就結束吧 再比也沒有意義了!)師父果然是師父!佩服!
			flag = false;
			// 大家安靜 還是老規矩 繼續...
			for (let j = 0; j < length; j++) {
				if (arr[j] > arr[j + 1]) {
					let temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
					// 如果此次迴圈有交換 則說明還得再來一輪,繼續往下比...這輪結束就發true給弟弟
					flag = true;
				}
			}
			length--;
		}
		console.log(`bubbleSortNoSoul1排序完成用了${count}輪`);
		return arr;
	}
複製程式碼

沒有靈魂版2(左右互博之術?副裁判得到周伯通真傳)

while弟弟被逼做數學題,比大小
副裁判備受周伯通喜歡,習得左右互博之術,並將之發揚光大...
複製程式碼
	bubbleSortNoSoul2 = (arr = []) => {
		let [j, temp, left, right, count] = [0, 0, 0, arr.length - 1, 0];
		while (left < right) {
			count++;
			for (j = left; j < right; j++) {
				if (arr[j] > arr[j + 1]) {
					temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
			right--;
			for (j = right; j > left; j--) {
				if (arr[j - 1] > arr[j]) {
					temp = arr[j];
					arr[j] = arr[j - 1];
					arr[j - 1] = temp;
				}
			}
			left++;
		}
		console.log(`bubbleSortNoSoul2排序完成用了${count}輪`);
		return arr;
	}
複製程式碼

沒有靈魂版3(flag心法+左右互博)

這場比武讓副裁判終成一代大俠...
複製程式碼
	bubbleSortNoSoul3 = (arr = []) => {
		let [j, temp, left, right, flag, count] = [0, 0, 0, arr.length - 1, true, 0];
		while (left < right && flag) {
			count++;
			flag = false;
			for (j = left; j < right; j++) {
				if (arr[j] > arr[j + 1]) {
					temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
					flag = true;
				}
			}
			right--;
			for (j = right; j > left; j--) {
				if (arr[j - 1] > arr[j]) {
					temp = arr[j];
					arr[j] = arr[j - 1];
					arr[j - 1] = temp;
					flag = true;
				}
			}
			left++;
		}
		console.log(`bubbleSortNoSoul3排序完成用了${count}輪`);
		return arr;
	}
複製程式碼

測試結果:

	let arr1 = [1, 2, 7, 8, 4, 5, 6, 3, 9];

	console.time('1');
	console.log(bubbleSortSoul1(arr1.concat()));  //8輪
	console.timeEnd('1');
	console.time('2');
	console.log(bubbleSortSoul2(arr1.concat()));  //8輪
	console.timeEnd('2');
	console.time('3');
	console.log(bubbleSortSoul3(arr1.concat()));  //8輪
	console.timeEnd('3');
	console.time('4');
	console.log(bubbleSortNoSoul1(arr1.concat()));//6輪
	console.timeEnd('4');
	console.time('5');
	console.log(bubbleSortNoSoul2(arr1.concat()));//4輪
	console.timeEnd('5');
	console.time('6');
	console.log(bubbleSortNoSoul3(arr1.concat()));//3輪
	console.timeEnd('6');
複製程式碼

node環境下測試結果

JS氣泡排序的6種寫法

注:

  • 汝輩豈知。——《三國演義》孔明空城計,司馬懿兩個兒子要攻城,司馬懿:汝輩豈知?宜速退。
  • 他強由他強 清風拂山崗 他橫由他橫 明月照大江。——出自金庸《倚天屠龍記》裡九陽真經。
  • 周伯通。——金庸《射鵰英雄傳》人物,曾將空明拳和雙手互博之術傳給郭靖。

相關文章