1. 程式人生 > >幾種基本的排序演算法總結

幾種基本的排序演算法總結

準備函式

	var arr = []
	function swap(arr, a, b) {  //交換函式
		var temp = arr[a]
		arr[a] = arr[b]
		arr[b] = temp
	}
	function random_arr (){  //生成隨機陣列的函式
		let long = Math.floor(Math.random()*100+1)
		for(var x = 0; x < long; x++) {
			arr.push(Math.floor(Math.random()*100))
		}
		console.log(arr)
	}
	random_arr
()

氣泡排序

演算法思路:

遍歷陣列, 將相鄰兩個數之間兩輛比較, 如果前面的數比後面的數大, 就交換位置, 然後繼續將這個數跟後面相鄰的數比較如果前面的數比後面的數小, 就用下一個數跟後面相鄰的數繼續比較

function bubble(arr) {
		for(var i = arr.length-1; i >= 0; i--) {
			for(var j = 0; j <= i; j++) {
				if(arr[j] > arr[j+1]) {
					swap(arr, j, j+1)
				}
			}
		}
		console.log(arr)
	}
bubble
(arr)

選擇排序

演算法思路:

將第一個數與後面的沒一個數進行比較, 如果有存在比第一個數小的數, 則交換位置, 然後用這個較小數繼續之前的位置向後比較, 經過一圈遍歷後, 陣列第一位的數就是跟個數組的最小值, 然後在用第二個數跟後面的所有數一次比較進行上述操作

	function chose(arr) {
		for(var i = 0; i<arr.length; i++) {
			for(var j = i+1; j<arr.length; j++) {
				if(arr[i] > arr[j]) {
					swap(arr, i, j)
				}
			}
} console.log(arr) } chose(arr)

插入排序

演算法思路:

遍歷整個陣列, 將遍歷項與其之前的項從後往前做比較, 如果他前面的數大於遍歷項, 則交換位置, 直到他前面的數小於遍歷項為止

	function fuck_sort(arr) {
		for(var i = 1; i < arr.length; i++) {
			for (var j = i; j > 0; j--) {
				if(arr[j]<arr[j-1]) {
					swap(arr, j, j-1)
				}
			}
		}
		console.log(arr)
	}
	fuck_sort(arr)

歸併排序

演算法思路:

將一個數組, 對半分割, 遞迴執行, 直到被分割後的陣列只剩下一個數, 然後利用外排的方式將分割好的陣列進行排序然後複寫到原陣列中 在這裡插入圖片描述

function guibing(arr,low,height) {
		var mid = low+Math.floor((height-low)/2)
		if(low === height) {
			return
		}
		guibing(arr, low, mid)
		guibing(arr, mid+1, height)
		sort(arr, low, height, mid)
	}
	function sort(arr, low, height, mid) {
		var temp = []
		var p1 = low
		var p2 = mid+1
		while (true){
			if (arr[p1] >= arr[p2]) {
				temp.push(arr[p2++])
			}else {
				temp.push(arr[p1++])
			}
			if(p1 > mid) {
				for(var j = p2; j <= height; j++) {
					temp.push(arr[j])
				}
				break
			}
			if(p2 > height) {
				for(var j = p1; j < mid+1; j++) {
					temp.push(arr[j])
				}
				break
			}
		}

		for(var i = 0; i <= temp.length-1; i++) {
			arr[i+low] = temp[i]
		}
	}
	guibing(arr, 0, arr.length-1)
	console.log(arr)

或者

function guibing2(arr) {
		if(arr.length === 1) {
			return arr
		}
		var mid = Math.floor(arr.length/2)
		var left = arr.slice(0,mid)  //slice()是陣列擷取方法
		var right = arr.slice(mid, arr.length)     
		return sort2(guibing2(left), guibing2(right))
	}
	function sort2(left, right) {
		var temp = []
		while(left.length > 0 && right.length > 0) {
			if(left[0] <= right[0]) {
				temp.push(left.shift())
			}else {
				temp.push(right.shift())
			}
		}
		return temp.concat(left).concat(right)   //concat()是陣列拼接方法
	}
	console.log(guibing2(arr))

快速排序

演算法思路:

在陣列中隨便找一個數做基準數, 將比這個基準數大的數放到這個數的右側, 將比這個基準數小的數, 放到這個數的左側, 然後在基準數的小於區和大於區繼續遞迴執行上述操作

function range(arr, l, r) {
		var less = l - 1
		var more = r
		while( l < more ) {
			if(arr[l] > arr[r]) {
				swap(arr, l, --more)
			}else if(arr[l] < arr[r]) {
				swap(arr, l++, ++less)
			}else {
				l++
			}
		}
		swap(arr, r, more)
		return [less+1,more]
	}
	function quick(arr, l, r) {
		if(l < r) {
			var scale = range(arr, l, r)
			quick(arr, l, scale[0]-1)
			quick(arr, scale[1]+1, r)
		}
	}
	quick(arr, 0, arr.length-1)
	console.log(arr)

或者

function quick2(arr) {
		if(arr.length === 0 ) {
			return []
		}
		var left = []
		var right = []
		var middle = []
		var index =Math.round(Math.random()*(arr.length-1))
		for(var i = 0; i<arr.length; i++) {
			if(arr[i] < arr[index]) {
				left.push(arr[i])
			}else if(arr[i] > arr[index]) {
				right.push(arr[i])
			}else {
				middle.push(arr[i])
			}
		}
		return quick2(left).concat(middle).concat(quick2(right))
	}
	console.log(quick2(arr))

堆排序

演算法思路:

因為堆的結構就是一個完全二叉樹, 所以我們可以把陣列的結構也想象成一個完全二叉樹, 首先將陣列變成一個大根堆, 然後將陣列的第一位與陣列的最後一位進行交換, 將陣列的遍歷範圍減少一位, 此時陣列的最後一位就是最大值了, 然後再將二叉樹的頭節點, 跟其左右兩孩子最大的那個作比較, 如果孩子節點大於父節點, 就交換位置, 然後利用原來的那個父節點繼續跟左右孩子作比較,比較結束後, 又形成了一個大根堆, 繼續將二叉樹的頭結點跟二叉樹的倒數第二位作交換, 將陣列的遍歷範圍再減少一位, 重複執行上述操作. 在這裡插入圖片描述

function dui_sort(arr) {
		dui(arr)
		var long = arr.length
		swap(arr, 0, --long)
		while(long > 0) {
			var j = 0
			var left = j*2+1
			while(left<long) {
				largest = left+1<long && arr[left+1] >arr[left] ? left+1 : left
				largest = arr[largest] > arr[j] ? largest : j
				if(largest === j) {
					break
				}
				swap(arr, largest, j)
				j = largest
				left = j*2+1
			}
			swap(arr, 0, --long)
		}
	}


	function dui(arr) {
		for(var i = 0; i < arr.length; i++) {
			var j = i
			while (arr[j] > arr[Math.floor((j-1)/2)]) {
				swap(arr, j, Math.floor((j-1)/2))
				j = Math.floor((j-1)/2)
			}
		}
	}
	dui_sort(arr)
	console.log(arr)