遊戲陪玩系統原始碼中不同排序演算法的實現方式
1 內部排序
function insertSort(arr) { //遍歷整個序列 for (let i = 0; i < arr.length; i++) { //當前待插入值 let temp = arr[i] //遍歷已排序序列,待插入值小則與前值交換 for (let j = i - 1; j >= 0 && arr[j] > temp; j--) { //解構賦值方式交換 [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]] } } return arr }
function midInsertSort(arr) { //折半向下取整 function absInt(a, b) { return Math.abs(parseInt((a + b) / 2)) } for (let i = 1; i < arr.length; i++) { let temp = arr[i]; let left = 0, right = i - 1, mid = absInt(left, right) let tag = 0 //折半查詢插入位置 while (left < right) { if (temp > arr[mid]) { left = mid + 1 mid = absInt(left, right) } else if (temp < arr[mid]) { right = mid - 1 mid = absInt(left, right) } else break } //保證穩定性 if (temp >= arr[mid]) tag = 1 //移動 for (let move = mid + tag; move <= i; move++) { [arr[move], temp] = [temp, arr[move]] } } return arr }
function shelltSort(arr) { //定義初始增量 let gap = Math.floor(arr.length / 2) //增量減至1時執行最後一次直接插入排序 while (gap >= 1) { //子序列的直接插入排序 for (let i = gap; i < arr.length; i += gap) { let temp = arr[i] for (let j = i - gap; j >= 0 && arr[j] > temp; j -= gap) { [arr[j], arr[j + gap]] = [arr[j + gap], arr[j]] } } //增量減半 gap = Math.floor(gap / 2) } return arr }
function bubbleSort(arr) { for (let i = 0; i < arr.length; i++) { for (let j = 0; j < arr.length - i - 1; j++) { if (arr[j] > arr[j + 1]) { [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]] } } } return arr }
function quickSort(arr, low, high) { //確定兩側指標 low = typeof low != 'number' ? 0 : low high = typeof high != 'number' ? arr.length - 1 : high; //指標重合結束迴圈 if (low < high) { //根據基準進行劃分,返回基準座標 let pivotIndex = partition(arr, low, high) //基準左側遞迴 quickSort(arr, low, pivotIndex - 1) //基準右側遞迴 quickSort(arr, pivotIndex + 1, high) } return arr } function partition(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 selectSort(arr) { for (let i = 0; i < arr.length - 1; i++) { let index = i for (let j = i + 1; j < arr.length; j++) { if (arr[j] < arr[index]) { index = j } } [arr[i], arr[index]] = [arr[index], arr[i]] } return arr }
function heapSort(arr) { let len = arr.length //建立一個大根堆 - 從最後一個非葉子節點開始,保證能比較交換出最大值 for (let i = Math.floor(len / 2 - 1); i >= 0; i--) { heapify(arr, i, len) } //交換當前堆頂與堆尾,堆尺寸減1,調整堆 for (let i = arr.length - 1; i > 0; i--) { [arr[0], arr[i]] = [arr[i], arr[0]] len-- //從對頂調整即可,次大值就是其左右子節點中的一個 heapify(arr, 0, len) } return arr } function heapify(arr, i, len) { //確定父節點的兩個子節點下標 let left = i * 2 + 1, right = i * 2 + 2, largest = i //找出父節點、左右子節點中的最大值,並標記下標 if (left < len && arr[left] > arr[largest]) largest = left if (right < len && arr[right] > arr[largest]) largest = right //最大值不是父節點 if (largest !== i) { //交換父節點與子節點的值 [arr[largest], arr[i]] = [arr[i], arr[largest]] //子節點向下繼續調整 heapify(arr, largest, len) } }
function radixSort(arr, maxDigit) { //初始化容器,進位制,被除數 let counter = [], mod = 10, dev = 1 //根據最大位數進行遍歷進桶 for (let i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) { //根據當前位按資料進桶 for (let j = 0; j < arr.length; j++) { let bucket = parseInt((arr[j] % mod) / dev) if (counter[bucket] == null) { counter[bucket] = [] } counter[bucket].push(arr[j]) } let pos = 0 //從小為桶號開始,先進桶的先出桶 for (let z = 0; z < counter.length; z++) { let value = null if (counter[z] != null) { while ((value = counter[z].shift()) != null) { arr[pos++] = value } } } } return arr }
2 外部排序
function mergeSort(arr) { //遞迴分治 - 直到長度為1 if (arr.length > 1) { let middle = Math.floor(arr.length / 2), left = mergeSort(arr.slice(0, middle)), right = mergeSort(arr.slice(middle)) arr = merge(left, right) } return arr } function merge(left, right) { //定義兩個指標,在左右序列中移動 let i = 0, j = 0, result = [] //雙指標法依次比較兩個序列的值, //選擇小值新增到result中,並移動其指標 //有一個移動結束迴圈結束 while (i < left.length && j < right.length) { result.push(left[i] < right[j] ? left[i++] : right[j++]) } //將另一個指標未移動結束序列的剩餘值與result進行拼接 return result.concat(i < left.length ? left.slice(i) : right.slice(j)) }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69996194/viewspace-2839377/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 遊戲陪玩系統原始碼中懶載入的實現方式有哪幾種?遊戲原始碼
- 陪玩平臺原始碼中的排序演算法,插入排序的實現原始碼排序演算法
- 如何在遊戲陪玩系統原始碼中實現“刮刮樂”效果?遊戲原始碼
- 如何實現遊戲陪玩系統原始碼前端效能監控?遊戲原始碼前端
- 遊戲陪玩系統實現自適應負載均衡演算法的方式遊戲負載演算法
- 帶你瞭解遊戲陪玩系統原始碼前端常用的儲存方式遊戲原始碼前端
- 如何在遊戲陪玩系統原始碼中聊天室內實現一個禮物系統?遊戲原始碼
- 遊戲陪玩原始碼的登入方式,簡訊驗證碼登入的實現遊戲原始碼
- 遊戲陪玩系統原始碼開發,如何實現圖片和動畫的優化?遊戲原始碼動畫優化
- 在遊戲陪玩原始碼開發中,兩種清空陣列的方式遊戲原始碼陣列
- 如何實現遊戲陪玩系統中語音的錄製與播放?遊戲
- 遊戲陪玩系統原始碼的許可權設計,如何基於位運算實現?遊戲原始碼
- 遊戲陪玩系統開發,音視訊混流的實現程式碼遊戲
- 透過websocket,實現遊戲陪玩系統的聊天室Web遊戲
- 如何在遊戲陪玩app原始碼中實現簡訊驗證碼登入?遊戲APP原始碼
- 陪玩系統原始碼實現音訊編碼的相關步驟原始碼音訊
- 陪玩系統原始碼中陣列去重的實現程式碼,簡單卻重要原始碼陣列
- 陪玩系統原始碼中mysql資料庫備份還原的實現程式碼原始碼MySql資料庫
- 關於遊戲陪玩系統原始碼後臺管理系統,需要思考的二三事遊戲原始碼
- 遊戲陪玩原始碼的移動端適配,應該如何實現?遊戲原始碼
- 陪玩系統原始碼開發,H5頁面中呼叫支付功能的實現原始碼H5
- 遊戲陪玩原始碼開發中,頁面跳轉方式及生命週期分析遊戲原始碼
- 遊戲陪玩系統開發,Java怎樣實現流合併?遊戲Java
- 如何開發陪玩系統原始碼的列表頁面,相關實現程式碼原始碼
- 遊戲陪玩平臺原始碼開發,依賴收集和觸發的實現遊戲原始碼
- 遊戲陪玩app原始碼開發,常用的倒數計時功能如何實現?遊戲APP原始碼
- 遊戲陪玩系統開發,日期時間選擇介面的實現遊戲
- 如何進行遊戲陪玩系統原始碼中音視訊的自動化測試?遊戲原始碼
- 遊戲陪玩系統,生成證書和金鑰庫的程式碼分析遊戲
- 遊戲陪玩系統開發,業務程式碼判斷生產/開發環境的方式遊戲開發環境
- 用 Go + Redis 實現陪玩平臺原始碼中的分散式鎖GoRedis原始碼分散式
- 做好陪玩系統原始碼的前端效能優化,提升系統效能原始碼前端優化
- 遊戲陪玩平臺原始碼,日期格式化的程式碼分析遊戲原始碼
- 遊戲陪玩app原始碼的可靠訊息最終一致性方案的實現遊戲APP原始碼
- 遊戲陪玩APP遊戲APP
- 如何使用 Redis 實現 陪玩原始碼中“附近的人” 這一功能?Redis原始碼
- 要想實現遊戲陪玩app原始碼的效能測試與調優,應該怎麼做?遊戲APP原始碼
- 遊戲陪玩平臺原始碼開發,聊天室內的禮物連擊效果的實現遊戲原始碼