Merge pull request #77 from jerryderry/master
merge_sort and quick_sort in python
This commit is contained in:
commit
ddcfd3d27e
@ -11,8 +11,8 @@ from typing import List
|
|||||||
def bubble_sort(a: List[int]):
|
def bubble_sort(a: List[int]):
|
||||||
if len(a) <= 1: return
|
if len(a) <= 1: return
|
||||||
|
|
||||||
made_swap = False
|
|
||||||
for i in range(len(a)):
|
for i in range(len(a)):
|
||||||
|
made_swap = False
|
||||||
for j in range(len(a) - i - 1):
|
for j in range(len(a) - i - 1):
|
||||||
if a[j] > a[j+1]:
|
if a[j] > a[j+1]:
|
||||||
a[j], a[j+1] = a[j+1], a[j]
|
a[j], a[j+1] = a[j+1], a[j]
|
||||||
|
48
python/12_sorts/merge_sort.py
Normal file
48
python/12_sorts/merge_sort.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
"""
|
||||||
|
Author: Wenru
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
def merge_sort(a: List[int]):
|
||||||
|
_merge_sort_between(a, 0, len(a)-1)
|
||||||
|
|
||||||
|
def _merge_sort_between(a: List[int], low: int, high: int):
|
||||||
|
# The indices are inclusive for both low and high.
|
||||||
|
if low >= high: return
|
||||||
|
mid = low + (high - low)//2
|
||||||
|
_merge_sort_between(a, low, mid)
|
||||||
|
_merge_sort_between(a, mid+1, high)
|
||||||
|
|
||||||
|
_merge(a, low, mid, high)
|
||||||
|
|
||||||
|
def _merge(a: List[int], low: int, mid: int, high: int):
|
||||||
|
# a[low:mid], a[mid+1, high] are sorted.
|
||||||
|
i, j = low, mid+1
|
||||||
|
tmp = []
|
||||||
|
while i <= mid and j <= high:
|
||||||
|
if a[i] <= a[j]:
|
||||||
|
tmp.append(a[i])
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
tmp.append(a[j])
|
||||||
|
j += 1
|
||||||
|
start = i if i <= mid else j
|
||||||
|
end = mid if i <= mid else high
|
||||||
|
tmp.extend(a[start:end+1])
|
||||||
|
a[low:high+1] = tmp
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
a1 = [3, 5, 6, 7, 8]
|
||||||
|
a2 = [2, 2, 2, 2]
|
||||||
|
a3 = [4, 3, 2, 1]
|
||||||
|
a4 = [5, -1, 9, 3, 7, 8, 3, -2, 9]
|
||||||
|
merge_sort(a1)
|
||||||
|
print(a1)
|
||||||
|
merge_sort(a2)
|
||||||
|
print(a2)
|
||||||
|
merge_sort(a3)
|
||||||
|
print(a3)
|
||||||
|
merge_sort(a4)
|
||||||
|
print(a4)
|
43
python/12_sorts/quick_sort.py
Normal file
43
python/12_sorts/quick_sort.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
"""
|
||||||
|
Author: Wenru
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import List
|
||||||
|
import random
|
||||||
|
|
||||||
|
def quick_sort(a: List[int]):
|
||||||
|
_quick_sort_between(a, 0, len(a)-1)
|
||||||
|
|
||||||
|
def _quick_sort_between(a: List[int], low: int, high: int):
|
||||||
|
if low >= high: return
|
||||||
|
# get a random position as the pivot
|
||||||
|
k = random.randint(low, high)
|
||||||
|
a[low], a[k] = a[k], a[low]
|
||||||
|
|
||||||
|
m = _partition(a, low, high) # a[m] is in final position
|
||||||
|
_quick_sort_between(a, low, m-1)
|
||||||
|
_quick_sort_between(a, m+1, high)
|
||||||
|
|
||||||
|
def _partition(a: List[int], low: int, high: int):
|
||||||
|
pivot, j = a[low], low
|
||||||
|
for i in range(low+1, high+1):
|
||||||
|
if a[i] <= pivot:
|
||||||
|
j += 1
|
||||||
|
a[j], a[i] = a[i], a[j] # swap
|
||||||
|
a[low], a[j] = a[j], a[low]
|
||||||
|
return j
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
a1 = [3, 5, 6, 7, 8]
|
||||||
|
a2 = [2, 2, 2, 2]
|
||||||
|
a3 = [4, 3, 2, 1]
|
||||||
|
a4 = [5, -1, 9, 3, 7, 8, 3, -2, 9]
|
||||||
|
quick_sort(a1)
|
||||||
|
print(a1)
|
||||||
|
quick_sort(a2)
|
||||||
|
print(a2)
|
||||||
|
quick_sort(a3)
|
||||||
|
print(a3)
|
||||||
|
quick_sort(a4)
|
||||||
|
print(a4)
|
BIN
swift/12_sorts/.DS_Store
vendored
Normal file
BIN
swift/12_sorts/.DS_Store
vendored
Normal file
Binary file not shown.
36
swift/12_sorts/QuickSort.swift
Normal file
36
swift/12_sorts/QuickSort.swift
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// QuickSort.swift
|
||||||
|
// algo
|
||||||
|
//
|
||||||
|
// Created by Wenru Dong on 2018/10/17.
|
||||||
|
// Copyright © 2018年 Wenru Dong. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public func quickSort<T: RandomAccessCollection & MutableCollection>(_ a: inout T) where T.Element: Comparable {
|
||||||
|
quickSort(&a, from: a.startIndex, to: a.index(before: a.endIndex))
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func quickSort<T: RandomAccessCollection & MutableCollection>(_ a: inout T, from low: T.Index, to high: T.Index) where T.Element: Comparable {
|
||||||
|
if low >= high { return }
|
||||||
|
|
||||||
|
let m = partition(&a, from: low, to: high)
|
||||||
|
quickSort(&a, from: low, to: a.index(before: m))
|
||||||
|
quickSort(&a, from: a.index(after: m), to: high)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func partition<T: RandomAccessCollection & MutableCollection>(_ a: inout T, from low: T.Index, to high: T.Index) -> T.Index where T.Element: Comparable {
|
||||||
|
let pivot = a[low]
|
||||||
|
var j = low
|
||||||
|
var i = a.index(after: low)
|
||||||
|
while i <= high {
|
||||||
|
if a[i] < pivot {
|
||||||
|
a.formIndex(after: &j)
|
||||||
|
a.swapAt(i, j)
|
||||||
|
}
|
||||||
|
a.formIndex(after: &i)
|
||||||
|
}
|
||||||
|
a.swapAt(low, j)
|
||||||
|
return j
|
||||||
|
}
|
58
swift/12_sorts/SortsTests.swift
Normal file
58
swift/12_sorts/SortsTests.swift
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// SortsTests.swift
|
||||||
|
// SortsTests
|
||||||
|
//
|
||||||
|
// Created by Wenru Dong on 2018/10/14.
|
||||||
|
// Copyright © 2018年 Wenru Dong. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
class SortsTests: XCTestCase {
|
||||||
|
|
||||||
|
override func setUp() {
|
||||||
|
super.setUp()
|
||||||
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() {
|
||||||
|
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||||
|
super.tearDown()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMergeSort() {
|
||||||
|
var a1 = [1, 1, 1, 1]
|
||||||
|
mergeSort(&a1)
|
||||||
|
XCTAssertEqual(a1, [1, 1, 1, 1])
|
||||||
|
|
||||||
|
var a2 = [4, 3, 2, 1]
|
||||||
|
mergeSort(&a2)
|
||||||
|
XCTAssertEqual(a2, [1, 2, 3, 4])
|
||||||
|
|
||||||
|
var a3 = [3, 6, 9, 7, 8, -1, 9, 3, -2, 0]
|
||||||
|
mergeSort(&a3)
|
||||||
|
XCTAssertEqual(a3, [-2, -1, 0, 3, 3, 6, 7, 8, 9, 9])
|
||||||
|
}
|
||||||
|
|
||||||
|
func testQuickSort() {
|
||||||
|
var a1 = [1, 1, 1, 1]
|
||||||
|
quickSort(&a1)
|
||||||
|
XCTAssertEqual(a1, [1, 1, 1, 1])
|
||||||
|
|
||||||
|
var a2 = [4, 3, 2, 1]
|
||||||
|
quickSort(&a2)
|
||||||
|
XCTAssertEqual(a2, [1, 2, 3, 4])
|
||||||
|
|
||||||
|
var a3 = [3, 6, 9, 7, 8, -1, 9, 3, -2, 0]
|
||||||
|
quickSort(&a3)
|
||||||
|
XCTAssertEqual(a3, [-2, -1, 0, 3, 3, 6, 7, 8, 9, 9])
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPerformanceExample() {
|
||||||
|
// This is an example of a performance test case.
|
||||||
|
self.measure {
|
||||||
|
// Put the code you want to measure the time of here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
52
swift/12_sorts/mergeSort.swift
Normal file
52
swift/12_sorts/mergeSort.swift
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// sorts.swift
|
||||||
|
// algo
|
||||||
|
//
|
||||||
|
// Created by Wenru Dong on 2018/10/14.
|
||||||
|
// Copyright © 2018年 Wenru Dong. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public func mergeSort<T>(_ a: inout T) where T: RandomAccessCollection, T: MutableCollection, T.Element: Comparable {
|
||||||
|
mergeSort(&a, from: a.startIndex, to: a.index(before: a.endIndex))
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func mergeSort<T>(_ a: inout T, from low: T.Index, to high: T.Index) where T: RandomAccessCollection, T: MutableCollection, T.Element: Comparable {
|
||||||
|
if low >= high { return }
|
||||||
|
let dist = a.distance(from: low, to: high)
|
||||||
|
let mid = a.index(low, offsetBy: dist/2)
|
||||||
|
mergeSort(&a, from: low, to: mid)
|
||||||
|
mergeSort(&a, from: a.index(mid, offsetBy: 1), to: high)
|
||||||
|
merge(&a, from: low, through: mid, to: high)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func merge<T>(_ a: inout T, from low: T.Index, through mid: T.Index, to high: T.Index) where T: RandomAccessCollection, T: MutableCollection, T.Element: Comparable {
|
||||||
|
var i = low
|
||||||
|
var j = a.index(mid, offsetBy: 1)
|
||||||
|
var tmp = Array<T.Element>()
|
||||||
|
tmp.reserveCapacity(a.distance(from: low, to: high) + 1)
|
||||||
|
while i <= mid && j <= high {
|
||||||
|
if a[i] <= a[j] {
|
||||||
|
tmp.append(a[i])
|
||||||
|
a.formIndex(after: &i)
|
||||||
|
} else {
|
||||||
|
tmp.append(a[j])
|
||||||
|
a.formIndex(after: &j)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var start = i
|
||||||
|
var end = mid
|
||||||
|
if j <= high {
|
||||||
|
start = j
|
||||||
|
end = high
|
||||||
|
}
|
||||||
|
tmp.append(contentsOf: a[start...end])
|
||||||
|
|
||||||
|
var current = low
|
||||||
|
for element in tmp {
|
||||||
|
a[current] = element
|
||||||
|
a.formIndex(after: ¤t)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user