比較相鄰的元素。如果第一個(gè)比第二個(gè)大,就交換他們兩個(gè)。
對每一對相鄰元素作同樣的工作,從開(kāi)始第一對到結尾的最后一對。這步做完后,最后的元素會(huì )是最大的數。
針對所有的元素重復以上的步驟,除了最后一個(gè)。
持續每次對越來(lái)越少的元素重復上面的步驟,直到?jīng)]有任何一對數字需要比較。
function bubbleSort(arr) {var len = arr.length;for (var i = 0; i < len - 1; i++) {for (var j = 0; j < len - 1 - i; j++) {if (arr[j] > arr[j+1]) { // 相鄰元素兩兩對比var temp = arr[j+1]; // 元素交換arr[j+1] = arr[j];arr[j] = temp;}}}return arr;}
def bubbleSort(arr):for i in range(1, len(arr)):for j in range(0, len(arr)-i):if arr[j] > arr[j+1]:arr[j], arr[j + 1] = arr[j + 1], arr[j]return arr
func bubbleSort(arr []int) []int {length := len(arr)for i := 0; i < length; i++ {for j := 0; j < length-1-i; j++ {if arr[j] > arr[j+1] {arr[j], arr[j+1] = arr[j+1], arr[j]}}}return arr}
首先在未排序序列中找到最?。ù螅┰?,存放到排序序列的起始位置
再從剩余未排序元素中繼續尋找最?。ù螅┰?,然后放到已排序序列的末尾。
重復第二步,直到所有元素均排序完畢。
function selectionSort(arr) {var len = arr.length;var minIndex, temp;for (var i = 0; i < len - 1; i++) {minIndex = i;for (var j = i + 1; j < len; j++) {if (arr[j] < arr[minIndex]) { // 尋找最小的數minIndex = j; // 將最小數的索引保存}}temp = arr[i];arr[i] = arr[minIndex];arr[minIndex] = temp;}return arr;}
def selectionSort(arr):for i in range(len(arr)-1):for j in range(i+1, len(arr)):if arr[j] < arr[i]:arr[i], arr[j] = arr[j], arr[i]return arr
func selectionSort(arr []int) []int {length := len(arr)for i := 0; i < length-1; i++ {min := ifor j := i + 1; j < length; j++ {if arr[min] > arr[j] {min = j}}arr[i], arr[min] = arr[min], arr[i]}return arr}
將第一待排序序列第一個(gè)元素看做一個(gè)有序序列,把第二個(gè)元素到最后一個(gè)元素當成是未排序序列。
從頭到尾依次掃描未排序序列,將掃描到的每個(gè)元素插入有序序列的適當位置。(如果待插入的元素與有序序列中的某個(gè)元素相等,則將待插入元素插入到相等元素的后面。)
function insertionSort(arr) {var len = arr.length;var preIndex, current;for (var i = 1; i < len; i++) {preIndex = i - 1;current = arr[i];while(preIndex >= 0 && arr[preIndex] > current) {arr[preIndex+1] = arr[preIndex];preIndex--;}arr[preIndex+1] = current;}return arr;}
def insertionSort(arr):for i in range(len(arr)):preIndex = i-1current = arr[i]while preIndex >= 0 and arr[preIndex] > current:arr[preIndex+1] = arr[preIndex]preIndex-=1arr[preIndex+1] = currentreturn arr
func insertionSort(arr []int) []int {for i := range arr {preIndex := i - 1current := arr[i]for preIndex >= 0 && arr[preIndex] > current {arr[preIndex+1] = arr[preIndex]preIndex -= 1}arr[preIndex+1] = current}return arr}
插入排序在對幾乎已經(jīng)排好序的數據操作時(shí),效率高,即可以達到線(xiàn)性排序的效率;
但插入排序一般來(lái)說(shuō)是低效的,因為插入排序每次只能將數據移動(dòng)一位;
選擇一個(gè)增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
按增量序列個(gè)數 k,對序列進(jìn)行 k 趟排序;
每趟排序,根據對應的增量 ti,將待排序列分割成若干長(cháng)度為 m 的子序列,分別對各子表進(jìn)行直接插入排序。僅增量因子為 1 時(shí),整個(gè)序列作為一個(gè)表來(lái)處理,表長(cháng)度即為整個(gè)序列的長(cháng)度。
function shellSort(arr) {var len = arr.length,temp,gap = 1;while(gap < len/3) { //動(dòng)態(tài)定義間隔序列gap =gap*3+1;}for (gap; gap > 0; gap = Math.floor(gap/3)) {for (var i = gap; i < len; i++) {temp = arr[i];for (var j = i-gap; j >= 0 && arr[j] > temp; j-=gap) {arr[j+gap] = arr[j];}arr[j+gap] = temp;}}return arr;}
def shellSort(arr):import mathgap=1while(gap < len(arr)/3):gap = gap*3+1while gap > 0:for i in range(gap,len(arr)):temp = arr[i]j = i-gapwhile j >=0 and arr[j] > temp:arr[j+gap]=arr[j]j-=gaparr[j+gap] = tempgap = math.floor(gap/3)return arr}
func shellSort(arr []int) []int {length := len(arr)gap := 1for gap < gap/3 {gap = gap*3 + 1}for gap > 0 {for i := gap; i < length; i++ {temp := arr[i]j := i - gapfor j >= 0 && arr[j] > temp {arr[j+gap] = arr[j]j -= gap}arr[j+gap] = temp}gap = gap / 3}return arr}
自上而下的遞歸(所有遞歸的方法都可以用迭代重寫(xiě),所以就有了第 2 種方法);
自下而上的迭代;
申請空間,使其大小為兩個(gè)已經(jīng)排序序列之和,該空間用來(lái)存放合并后的序列;
設定兩個(gè)指針,最初位置分別為兩個(gè)已經(jīng)排序序列的起始位置;
比較兩個(gè)指針所指向的元素,選擇相對小的元素放入到合并空間,并移動(dòng)指針到下一位置;
重復步驟 3 直到某一指針達到序列尾;
將另一序列剩下的所有元素直接復制到合并序列尾。
function mergeSort(arr) { // 采用自上而下的遞歸方法var len = arr.length;if(len < 2) {return arr;}var middle = Math.floor(len / 2),left = arr.slice(0, middle),right = arr.slice(middle);return merge(mergeSort(left), mergeSort(right));}function merge(left, right){var result = [];while (left.length && right.length) {if (left[0] <= right[0]) {result.push(left.shift());} else {result.push(right.shift());}}while (left.length)result.push(left.shift());while (right.length)result.push(right.shift());return result;}
def mergeSort(arr):import mathif(len(arr)<2):return arrmiddle = math.floor(len(arr)/2)left, right = arr[0:middle], arr[middle:]return merge(mergeSort(left), mergeSort(right))def merge(left,right):result = []while left and right:if left[0] <= right[0]:result.append(left.pop(0));else:result.append(right.pop(0));while left:result.append(left.pop(0));while right:result.append(right.pop(0));return result
func mergeSort(arr []int) []int {length := len(arr)if length < 2 {return arr}middle := length / 2left := arr[0:middle]right := arr[middle:]return merge(mergeSort(left), mergeSort(right))}func merge(left []int, right []int) []int {var result []intfor len(left) != 0 && len(right) != 0 {if left[0] <= right[0] {result = append(result, left[0])left = left[1:]} else {result = append(result, right[0])right = right[1:]}}for len(left) != 0 {result = append(result, left[0])left = left[1:]}for len(right) != 0 {result = append(result, right[0])right = right[1:]}return result}
從數列中挑出一個(gè)元素,稱(chēng)為 “基準”(pivot);
重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的后面(相同的數可以到任一邊)。在這個(gè)分區退出之后,該基準就處于數列的中間位置。這個(gè)稱(chēng)為分區(partition)操作;
遞歸地(recursive)把小于基準值元素的子數列和大于基準值元素的子數列排序;

function quickSort(arr, left, right) {var len = arr.length,partitionIndex,left = typeof left != 'number' ? 0 : left,right = typeof right != 'number' ? len - 1 : right;if (left < right) {partitionIndex = partition(arr, left, right);quickSort(arr, left, partitionIndex-1);quickSort(arr, partitionIndex+1, right);}return arr;}function partition(arr, left ,right) { // 分區操作var pivot = left, // 設定基準值(pivot)index = pivot + 1;for (var i = index; i <= right; i++) {if (arr[i] < arr[pivot]) {swap(arr, i, index);index++;}}swap(arr, pivot, index - 1);return index-1;}function swap(arr, i, j) {var temp = arr[i];arr[i] = arr[j];arr[j] = temp;}functiion paritition2(arr, low, high) {let pivot = arr[low];while (low < high) {while (low < high && arr[high] > pivot) {--high;}arr[low] = arr[high];while (low < high && arr[low] <= pivot) {++low;}arr[high] = arr[low];}arr[low] = pivot;return low;}function quickSort2(arr, low, high) {if (low < high) {let pivot = paritition2(arr, low, high);quickSort2(arr, low, pivot - 1);quickSort2(arr, pivot + 1, high);}return arr;}
def quickSort(arr, left=None, right=None):left = 0 if not isinstance(left,(int, float)) else leftright = len(arr)-1 if not isinstance(right,(int, float)) else rightif left < right:partitionIndex = partition(arr, left, right)quickSort(arr, left, partitionIndex-1)quickSort(arr, partitionIndex+1, right)return arrdef partition(arr, left, right):pivot = leftindex = pivot+1i = indexwhile i <= right:if arr[i] < arr[pivot]:swap(arr, i, index)index+=1i+=1swap(arr,pivot,index-1)return index-1def swap(arr, i, j):arr[i], arr[j] = arr[j], arr[i]
func quickSort(arr []int) []int {return _quickSort(arr, 0, len(arr)-1)}func _quickSort(arr []int, left, right int) []int {if left < right {partitionIndex := partition(arr, left, right)_quickSort(arr, left, partitionIndex-1)_quickSort(arr, partitionIndex+1, right)}return arr}func partition(arr []int, left, right int) int {pivot := leftindex := pivot + 1for i := index; i <= right; i++ {if arr[i] < arr[pivot] {swap(arr, i, index)index += 1}}swap(arr, pivot, index-1)return index - 1}func swap(arr []int, i, j int) {arr[i], arr[j] = arr[j], arr[i]}
//標準分割函數Paritition1(int A[], int low, int high) {int pivot = A[low];while (low < high) {while (low < high && A[high] >= pivot) {--high;}A[low] = A[high];while (low < high && A[low] <= pivot) {++low;}A[high] = A[low];}A[low] = pivot;return low;}void QuickSort(int A[], int low, int high) //快排母函數{if (low < high) {int pivot = Paritition1(A, low, high);QuickSort(A, low, pivot - 1);QuickSort(A, pivot + 1, high);}}
大頂堆:每個(gè)節點(diǎn)的值都大于或等于其子節點(diǎn)的值,在堆排序算法中用于升序排列;
小頂堆:每個(gè)節點(diǎn)的值都小于或等于其子節點(diǎn)的值,在堆排序算法中用于降序排列;
var len; // 因為聲明的多個(gè)函數都需要數據長(cháng)度,所以把len設置成為全局變量function buildMaxHeap(arr) { // 建立大頂堆len = arr.length;for (var i = Math.floor(len/2); i >= 0; i--) {heapify(arr, i);}}function heapify(arr, i) { // 堆調整var left = 2 * i + 1,right = 2 * i + 2,largest = i;if (left < len && arr[left] > arr[largest]) {largest = left;}if (right < len && arr[right] > arr[largest]) {largest = right;}if (largest != i) {swap(arr, i, largest);heapify(arr, largest);}}function swap(arr, i, j) {var temp = arr[i];arr[i] = arr[j];arr[j] = temp;}function heapSort(arr) {buildMaxHeap(arr);for (var i = arr.length-1; i > 0; i--) {swap(arr, 0, i);len--;heapify(arr, 0);}return arr;}
def buildMaxHeap(arr):import mathfor i in range(math.floor(len(arr)/2),-1,-1):heapify(arr,i)def heapify(arr, i):left = 2*i+1right = 2*i+2largest = iif left < arrLen and arr[left] > arr[largest]:largest = leftif right < arrLen and arr[right] > arr[largest]:largest = rightif largest != i:swap(arr, i, largest)heapify(arr, largest)def swap(arr, i, j):arr[i], arr[j] = arr[j], arr[i]def heapSort(arr):global arrLenarrLen = len(arr)buildMaxHeap(arr)for i in range(len(arr)-1,0,-1):swap(arr,0,i)arrLen -=1heapify(arr, 0)return arr
func heapSort(arr []int) []int {arrLen := len(arr)buildMaxHeap(arr, arrLen)for i := arrLen - 1; i >= 0; i-- {swap(arr, 0, i)arrLen -= 1heapify(arr, 0, arrLen)}return arr}func buildMaxHeap(arr []int, arrLen int) {for i := arrLen / 2; i >= 0; i-- {heapify(arr, i, arrLen)}}func heapify(arr []int, i, arrLen int) {left := 2*i + 1right := 2*i + 2largest := iif left < arrLen && arr[left] > arr[largest] {largest = left}if right < arrLen && arr[right] > arr[largest] {largest = right}if largest != i {swap(arr, i, largest)heapify(arr, largest, arrLen)}}func swap(arr []int, i, j int) {arr[i], arr[j] = arr[j], arr[i]}

function countingSort(arr, maxValue) {var bucket = new Array(maxValue+1),sortedIndex = 0;arrLen = arr.length,bucketLen = maxValue + 1;for (var i = 0; i < arrLen; i++) {if (!bucket[arr[i]]) {bucket[arr[i]] = 0;}bucket[arr[i]]++;}for (var j = 0; j < bucketLen; j++) {while(bucket[j] > 0) {arr[sortedIndex++] = j;bucket[j]--;}}return arr;}
def countingSort(arr, maxValue):bucketLen = maxValue+1bucket = [0]*bucketLensortedIndex =0arrLen = len(arr)for i in range(arrLen):if not bucket[arr[i]]:bucket[arr[i]]=0bucket[arr[i]]+=1for j in range(bucketLen):while bucket[j]>0:arr[sortedIndex] = jsortedIndex+=1bucket[j]-=1return arr
func countingSort(arr []int, maxValue int) []int {bucketLen := maxValue + 1bucket := make([]int, bucketLen) // 初始為0的數組sortedIndex := 0length := len(arr)for i := 0; i < length; i++ {bucket[arr[i]] += 1}for j := 0; j < bucketLen; j++ {for bucket[j] > 0 {arr[sortedIndex] = jsortedIndex += 1bucket[j] -= 1}}return arr}
在額外空間充足的情況下,盡量增大桶的數量
使用的映射函數能夠將輸入的 N 個(gè)數據均勻的分配到 K 個(gè)桶中
function bucketSort(arr, bucketSize) {if (arr.length === 0) {return arr;}var i;var minValue = arr[0];var maxValue = arr[0];for (i = 1; i < arr.length; i++) {if (arr[i] < minValue) {minValue = arr[i]; // 輸入數據的最小值} else if (arr[i] > maxValue) {maxValue = arr[i]; // 輸入數據的最大值}}//桶的初始化var DEFAULT_BUCKET_SIZE = 5; // 設置桶的默認數量為5bucketSize = bucketSize || DEFAULT_BUCKET_SIZE;var bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;var buckets = new Array(bucketCount);for (i = 0; i < buckets.length; i++) {buckets[i] = [];}//利用映射函數將數據分配到各個(gè)桶中for (i = 0; i < arr.length; i++) {buckets[Math.floor((arr[i] - minValue) / bucketSize)].push(arr[i]);}arr.length = 0;for (i = 0; i < buckets.length; i++) {insertionSort(buckets[i]); // 對每個(gè)桶進(jìn)行排序,這里使用了插入排序for (var j = 0; j < buckets[i].length; j++) {arr.push(buckets[i][j]);}}return arr;}

//LSD Radix Sortvar counter = [];function radixSort(arr, maxDigit) {var mod = 10;var dev = 1;for (var i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {for(var j = 0; j < arr.length; j++) {var bucket = parseInt((arr[j] % mod) / dev);if(counter[bucket]==null) {counter[bucket] = [];}counter[bucket].push(arr[j]);}var pos = 0;for(var j = 0; j < counter.length; j++) {var value = null;if(counter[j]!=null) {while ((value = counter[j].shift()) != null) {arr[pos++] = value;}}}}return arr;}

聯(lián)系客服