排序
最后更新于
这有帮助吗?
从数组中随机选择一个基准值t
将小于基准值的元素放到low中,将等于基准值的元素放到mid中,将大于基准值的元素放到high中
递归排序low数组,递归排序high数组
合并数组 low+mid+high
from random import randint
# 借助额外数组,容易理解
def quick_sort_with_help(nums: list) -> list:
if len(nums) <= 1:
return nums
rd = randint(0, len(nums) - 1)
low = list()
mid = list()
high = list()
for a in nums:
if a < nums[rd]:
low.append(a)
elif a > nums[rd]:
high.append(a)
else:
mid.append(a)
low = quick_sort_with_help(low)
high = quick_sort_with_help(high)
low.extend(mid)
low.extend(high)
return low
判断排序区间是否合法
初始化左右指针
选取目标值(此处选择的是中点,也可以随机选择,但在此代码中请注意选择随机值的范围应该是[left+1, right))
使left指针指向第一个不小于目标值的元素
使right指针指向第一个不大于目标值的元素
如果left < right则交换两个指针指向的元素
def quick_sort(nums: list, start: int, end: int):
if start >= end:
return
# 双指针
left, right = start - 1, end + 1 # 这样初始化是为了减少边界判断
t = nums[left + ((right - left) >> 1)]
while left < right:
left += 1
while nums[left] < t:
left += 1
right -= 1
while nums[right] > t:
right -= 1
if left < right:
nums[left], nums[right] = nums[right], nums[left]
quick_sort(nums, start, right)
quick_sort(nums, right + 1, end)
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
var reader = bufio.NewReader(os.Stdin)
readInt(reader)
var x = readArray(reader)
QuickSort(x, 0, len(x)-1)
fmt.Println(nums2string(x, " "))
}
func QuickSort(nums []int, start, end int) {
if start >= end {
return
}
var (
// 这样初始化是为了减少边界判断
left = start - 1
right = end + 1
midValue = nums[left+((right-left)>>1)]
)
for left < right {
left++
// 寻找左边不小于midValue的元素,往右移动
for nums[left] < midValue {
left++
}
right--
// 寻找右边不大于midValue的元素,往左移动
for nums[right] > midValue {
right--
}
if left < right {
nums[left], nums[right] = nums[right], nums[left]
}
}
QuickSort(nums, start, right)
QuickSort(nums, right+1, end)
}
func readLine(reader *bufio.Reader) string {
var line, _ = reader.ReadString('\n')
return strings.TrimRight(line, "\n")
}
func readInt(reader *bufio.Reader) int {
var num, _ = strconv.Atoi(readLine(reader))
return num
}
func readArray(reader *bufio.Reader) []int {
var line = readLine(reader)
var strList = strings.Split(line, " ")
var nums = make([]int, 0)
var err error
var v int
for i := 0; i < len(strList); i++ {
if v, err = strconv.Atoi(strList[i]); err != nil {
continue
}
nums = append(nums, v)
}
return nums
}
func nums2string(x []int, sep string) string {
var b strings.Builder
for i := 0; i < len(x); i++ {
b.WriteString(strconv.Itoa(x[i]))
b.WriteString(sep)
}
return b.String()
}
折半拆分数组,排序左半边数组,排序右半边数组
外排合并左半边数组和右半边数组
def merge_sort(nums: list) -> list:
if len(nums) <= 1:
return nums
mid = len(nums) >> 1
return merge(merge_sort(nums[:mid]), merge_sort(nums[mid:]))
def merge(a: list, b: list) -> list:
ans = list()
ai = bi = 0
while ai < len(a) and bi < len(b):
if a[ai] <= b[bi]:
ans.append(a[ai])
ai += 1
else:
ans.append(b[bi])
bi += 1
if ai < len(a):
ans.extend(a[ai:])
if bi < len(b):
ans.extend(b[bi:])
return ans
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
var reader = bufio.NewReader(os.Stdin)
readInt(reader)
var x = readArray(reader)
fmt.Println(nums2string(MergeSort(x), " "))
}
func MergeSort(x []int) []int {
if len(x) <= 1 {
return x
}
return merge(MergeSort(x[0:len(x)>>1]), MergeSort(x[len(x)>>1:]))
}
func merge(a, b []int) []int {
var (
i int
j int
ans []int
)
for i < len(a) && j < len(b) {
if a[i] < b[j] {
ans = append(ans, a[i])
i++
} else {
ans = append(ans, b[j])
j++
}
}
if i < len(a) {
ans = append(ans, a[i:]...)
}
if j < len(b) {
ans = append(ans, b[j:]...)
}
return ans
}
func readLine(reader *bufio.Reader) string {
var line, _ = reader.ReadString('\n')
return strings.TrimRight(line, "\n")
}
func readInt(reader *bufio.Reader) int {
var num, _ = strconv.Atoi(readLine(reader))
return num
}
func readArray(reader *bufio.Reader) []int {
var line = readLine(reader)
var strList = strings.Split(line, " ")
var nums = make([]int, 0)
var err error
var v int
for i := 0; i < len(strList); i++ {
if v, err = strconv.Atoi(strList[i]); err != nil {
continue
}
nums = append(nums, v)
}
return nums
}
func nums2string(x []int, sep string) string {
var b strings.Builder
for i := 0; i < len(x); i++ {
b.WriteString(strconv.Itoa(x[i]))
b.WriteString(sep)
}
return b.String()
}
cnt = 0
def merge_sort(nums: list) -> list:
if len(nums) <= 1:
return nums
mid = len(nums) >> 1
return merge(merge_sort(nums[:mid]), merge_sort(nums[mid:]))
def merge(a: list, b: list) -> list:
ans = list()
ai = bi = 0
while ai < len(a) and bi < len(b):
if a[ai] <= b[bi]:
ans.append(a[ai])
ai += 1
else:
ans.append(b[bi])
global cnt
cnt += len(a) - ai
bi += 1
if ai < len(a):
ans.extend(a[ai:])
if bi < len(b):
ans.extend(b[bi:])
return ans
input()
nums = [int(x) for x in input().split(" ")]
merge_sort(nums)
print(cnt)
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
var c int
func main() {
var reader = bufio.NewReader(os.Stdin)
readInt(reader)
var x = readArray(reader)
MergeSort(x)
fmt.Println(c)
c = 0
}
func MergeSort(x []int) []int {
if len(x) <= 1 {
return x
}
return merge(MergeSort(x[0:len(x)>>1]), MergeSort(x[len(x)>>1:]))
}
func merge(a, b []int) []int {
var (
i int
j int
ans []int
)
for i < len(a) && j < len(b) {
if a[i] <= b[j] {
ans = append(ans, a[i])
i++
} else {
// a[i:]列表中的元素与b[j]都构成逆序对
ans = append(ans, b[j])
c += len(a[i:])
j++
}
}
if i < len(a) {
ans = append(ans, a[i:]...)
}
if j < len(b) {
ans = append(ans, b[j:]...)
}
return ans
}
func readLine(reader *bufio.Reader) string {
var line, _ = reader.ReadString('\n')
return strings.TrimRight(line, "\n")
}
func readInt(reader *bufio.Reader) int {
var num, _ = strconv.Atoi(readLine(reader))
return num
}
func readArray(reader *bufio.Reader) []int {
var line = readLine(reader)
var strList = strings.Split(line, " ")
var nums = make([]int, 0)
var err error
var v int
for i := 0; i < len(strList); i++ {
if v, err = strconv.Atoi(strList[i]); err != nil {
continue
}
nums = append(nums, v)
}
return nums
}
func nums2string(x []int, sep string) string {
var b strings.Builder
for i := 0; i < len(x); i++ {
b.WriteString(strconv.Itoa(x[i]))
b.WriteString(sep)
}
return b.String()
}