golang快速排序算法

快速排序算法原理:

設置分水嶺,把小於分水嶺的數排到分水嶺左側,其餘的排到右側,遞歸的對分水嶺兩側的元素做同樣的處理


package qsort

func quickSort(values []int, left int, right int) {
	if left < right {

		// 設置分水嶺
		temp := values[left]

		// 設置哨兵
		i, j := left, right
		for {
			// 從右向左找,找到第一個比分水嶺小的數
			for values[j] >= temp && i < j {
				j--
			}

			// 從左向右找,找到第一個比分水嶺大的數
			for values[i] <= temp && i < j {
				i++
			}

			// 如果哨兵相遇,則退出循環
			if i >= j {
				break
			}

			// 交換左右兩側的值
			values[i], values[j] = values[j], values[i]
		}

		// 將分水嶺移到哨兵相遇點
		values[left] = values[i]
		values[i] = temp

		// 遞歸,左右兩側分別排序
		quickSort(values, left, i-1)
		quickSort(values, i+1, right)
	}
}

func QuickSort(values []int) {
	quickSort(values, 0, len(values)-1)
}

更簡潔的版本:

package main

import "fmt"

func main() {
   numbers := []int{6, 2, 7, 7, 3, 8, 9}
   //fmt.Println(numbers)
   QuickSort(numbers)

   fmt.Println(numbers)
}

func QuickSort(values []int) {
   length := len(values)
   if length <= 1 {
      return
   }
   mid, i := values[0], 1    // 取第一個元素作爲分水嶺,i下標初始爲1,即分水嶺右側的第一個元素的下標
   head, tail := 0, length-1 // 頭尾的下標

   // 如果頭和尾沒有相遇,就會一直觸發交換
   for head < tail {
      fmt.Println(values, head, tail, i)
      if values[i] > mid {
         // 如果分水嶺右側的元素大於分水嶺,就將右側的尾部元素和分水嶺右側元素交換
         values[i], values[tail] = values[tail], values[i]
         tail-- // 尾下標左移一位
      } else {
         // 如果分水嶺右側的元素小於等於分水嶺,就將分水嶺右移一位
         values[i], values[head] = values[head], values[i]
         head++ // 頭下標右移一位
         i++    // i下標右移一位
      }
      fmt.Printf("----{head:%d,tail:%d,i:%d,mid:%d} values:%v\n", head, tail, i, mid, values)
   }

   // 分水嶺左右的元素遞歸做同樣處理
   QuickSort(values[:head])
   QuickSort(values[head+1:])
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章