GO 語言常用排序

来源:https://www.cnblogs.com/lurenq/archive/2019/12/23/12089175.html
-Advertisement-
Play Games

1. 冒泡排序(bubble sort)的基本思想:比較相鄰兩個 元素的關鍵字值,如果反序,則交換 2. 快速排序 快速排序(quick sort)是一種分區交換排序演算法. 它的基本思想:在數據序列中選擇一個值作為比較的基準值, 每趟從數據序列的兩端開始交替進行,將小於基準值的元素交換到序列前端,將 ...


1. 冒泡排序(bubble sort)的基本思想:比較相鄰兩個 元素的關鍵字值,如果反序,則交換

func BubbleSort(arr []int) {
	flag := false
	//外層控制行
	for i := 0; i < len(arr)-1; i++ {
		//內層控制列
		for j := 0; j < len(arr)-1-i; j++  {
			//比較兩個相鄰元素
			if arr[j] > arr[j+1] {
				//交換數據
				arr[j], arr[j+1] = arr[j+1], arr[j]
				flag = true
			}
		}
		//判斷數據是否是有序
		if !flag {
			return
		} else {
			flag = false
		}
	}
}

 2. 快速排序

快速排序(quick sort)是一種分區交換排序演算法.

它的基本思想:在數據序列中選擇一個值作為比較的基準值, 每趟從數據序列的兩端開始交替進行,將小於基準值的元素交換到序列前端,將大於基準值的元素交換到序列後端, 介於兩者之間的位置則成為基準值的最終位置。

func QuickSort(arr []int, left int, right int) {
	//設置基準值
	temp := arr[left]
	index := left

	i := left
	j := right

	for i <= j {
		//從右面找到比基準值小的數據
		for j >= index && arr[j] >= temp {
			j--
		}
		//獲取基準值合適下標
		if j > index {
			arr[index] = arr[j]
			index = j
		}
		//從左面找比基準值大的數據
		for i <= index && arr[i] <= temp {
			i++
		}
		//獲取基準值合適下標
		if i <= index {
			arr[index] = arr[i]
			index = i
		}
	}
	//將基準值放在合適位置
	arr[index] = temp

	//遞歸調用 分步處理數據
	if index-left > 1 {
		QuickSort(arr, left, index-1)
	}
	if right-index > 1 {
		QuickSort(arr, index+1, right)
	}

}

3. 直接選擇排序

直接選擇排序(straight select sort)的基本思想:第一趟從n個元素的數據序列中選出關鍵字最小(或最大)的元素並放到最前(或最後)位置,下一趟再從n-1個元素中選出最小(大)的元素並放到次前(後)位置,以此類推,經過n-1趟完成排序。

func SelectSort(arr []int) {

	//外層控制行
	for i := 0; i < len(arr); i++ {
		//記錄最大值下標
		index := 0
		//內層控制列
		//遍曆數據 查找最大值
		for j := 1; j < len(arr)-i; j++ {
			if arr[j] > arr[index] {
				//記錄下標
				index = j
			}
		}

		//交換數據
		arr[index], arr[len(arr)-1-i] = arr[len(arr)-1-i], arr[index]
	}
}

4.堆排序

堆排序(heap sort)是完全二叉樹的應用,它的基本思想:將數據序列“堆”成樹狀,每趟只遍歷樹中的一條路徑。

//初始化堆
func HeapInit(arr []int) {

	//將切片轉成二叉樹模型  實現大根堆
	length := len(arr)
	for i := length/2 - 1; i >= 0; i-- {
		HeapSort(arr, i, length-1)
	}

	//根節點存儲最大值
	for i := length - 1; i > 0; i-- {
		//如果只剩下根節點和跟節點下的左子節點
		if i == 1 && arr[0] <= arr[i] {
			break
		}
		//將根節點和葉子節點數據交換
		arr[0], arr[i] = arr[i], arr[0]
		HeapSort(arr, 0, i-1)
	}

}

//獲取堆中最大值  放在根節點
func HeapSort(arr []int, startNode int, maxNode int) {

	//最大值放在根節點
	var max int
	//定義做左子節點和右子節點
	lChild := startNode*2 + 1
	rChild := lChild + 1
	//子節點超過比較範圍 跳出遞歸
	if lChild >= maxNode {
		return
	}
	//左右比較  找到最大值
	if rChild <= maxNode && arr[rChild] > arr[lChild] {
		max = rChild
	} else {
		max = lChild
	}

	//和跟節點比較
	if arr[max] <= arr[startNode] {
		return
	}

	//交換數據
	arr[startNode], arr[max] = arr[max], arr[startNode]
	//遞歸進行下次比較
	HeapSort(arr, max, maxNode)
}

5. 插入排序

func InsertSort(arr []int) {
	for i := 1; i < len(arr); i++ {
		//如果當前數據小於有序數據
		if arr[i] < arr[i-1] {
			j := i - 1
			//獲取有效數據
			temp := arr[i]
			//一次比較有序數據
			for j >= 0 && arr[j] > temp {
				arr[j+1] = arr[j]
				j--
			}
			arr[j+1] = temp
		}
	}
}

 6. 希爾排序

希爾排序(shell sort)又稱縮小增量排序,它的基本思想:分組的直接插入排序。

func ShellSort(arr []int) {
	//根據增量(len(arr)/2)每次變成上一次的1/2
	for inc := len(arr) / 2; inc > 0; inc /= 2 {

		for i := inc; i < len(arr); i++ {
			temp := arr[i]

			//根據增量從數據到0進行比較
			for j := i - inc; j >= 0; j -= inc {
				//滿足條件交換數據
				if temp < arr[j] {
					arr[j], arr[j+inc] = arr[j+inc], arr[j]
				} else {
					break
				}
			}
		}
	}
}

 7. 二分查找 BinarySearch(數據,元素) 返回值為下標

package main

import "fmt"

func BinarySearch(arr []int, num int) int {
	//定義起始下標
	start := 0
	//定義結束下標
	end := len(arr) - 1
	//中間基準值
	mid := (start + end) / 2

	for i := 0; i < len(arr); i++ {
		//基準值為查找值
		if num == arr[mid] {
			return mid
		} else if num > arr[mid] {
			//比基準值大  查找右側
			start = mid + 1
		} else {
			//比基準值小  查找左側
			end = mid - 1
		}
		//再次設置中間基準值位置
		mid = (start + end) / 2
	}
	return -1
}
func main() {
	//前提必須是 "有序數據"
	arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	num := 666

	index := BinarySearch(arr, num)
	fmt.Println(index)
}

 8. 變相排序

變相排序  基於大量重覆 在某一個範圍內

func main02() {
	//隨機數種子
	rand.Seed(time.Now().UnixNano())
	s := make([]int, 0)

	for i := 0; i < 10000; i++ {
		s = append(s, rand.Intn(1000)) //0-999
	}
	fmt.Println(s)

	//統計數據集合中數據出現的次數
	m := make(map[int]int)
	for i := 0; i < len(s); i++ {
		m[s[i]]++
	}
	//fmt.Println(m)

	//排序
	for i := 0; i < 1000; i++ {
		for j := 0; j < m[i]; j++ {
			fmt.Print(i, " ")
		}
	}

}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 分割線是網頁中比較常見的一類設計了,比如說知乎的更多回答 這裡的自適應是指兩邊的橫線會隨著文字的個數和父級的寬度自適應 偷偷的看了一下知乎的實現,很顯然是用一塊白色背景覆蓋的,加一點背景就露餡了 心想:知乎的前端也不怎麼樣? 可能別人的重點不在這些上面吧 下麵列舉幾種更好的實現方式,不會露餡的那種 ...
  • 案例:旋轉木馬 頁面載入時候出現的效果,script標簽寫在head裡面,body上面 顯示一個圖片散開的動畫,遍歷之後,把每個圖片用封裝的動畫函數移動到指定目標(同時改變多屬性:寬,透明度,層級,top, left) 在做左右按鈕點擊事件。 右邊按鈕,用數組裡面的push和shift,數組第一個去 ...
  • 在項目運行過程中發現,用戶在有左右滑動前進後退的功能的瀏覽器上簽字時,偶然觸發了前進後退會導致canvas像是重置了一樣內容消失,所以需要在代碼中處理這種情況。 基本原理就是在touchmove事件中阻止預設事件,使瀏覽器不會觸發前進後退事件,但是也會無法觸發scroll事件讓頁面正常滾動,後續如何 ...
  • 循序漸進,看看只使用 CSS ,可以鼓搗出什麼樣的充電動畫效果。 畫個電池 當然,電池充電,首先得用 CSS 畫一個電池,這個不難,隨便整一個: 歐了,勉強就是它了。有了電池,那接下來直接充電吧。最最簡單的動畫,那應該是用色彩把整個電池灌滿即可。 方法很多,代碼也很簡單,直接看效果: 有內味了,如果 ...
  • 樣式操作模塊可用於管理DOM元素的樣式、坐標和尺寸,本節講解一下尺寸這一塊 jQuery通過樣式操作模塊里的尺寸相關的API可以很方便的獲取一個元素的寬度、高度,而且可以很方便的區分padding、border、 margin等,主要有六個API,如下: heihgt(size)、width(siz ...
  • Proise實例的then方法是定義在原型對象Promise.prototype上的,它的作用是為Promise實例添加狀態改變時的回調函數。 該方法可以接收兩個回調函數作為參數,其中第二個回調函數是可選的。第一個回調函數是 對象的狀態變為 時調用,第二個回調函數是 對象的狀態變為 時調用。 下麵從 ...
  • 一、finally語句塊 1.註意點: (1)finally語句塊可以直接和try語句塊聯合使用。try...finally.... (2)try.....catch.....finally也可以執行; (3)在finally語句塊中的代碼是一定會執行的。 package com.bjpowerno ...
  • package main import ( "fmt" "reflect" ) type BinaryNode struct { Data interface{} //數據 lChild *BinaryNode //左子樹 rChild *BinaryNode //右子樹 } //創建二叉樹 fun... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...