Merge pull request #77 from jerryderry/master

merge_sort and quick_sort in python
This commit is contained in:
wangzheng0822 2018-10-23 10:23:57 +08:00 committed by GitHub
commit ddcfd3d27e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 238 additions and 1 deletions

View File

@ -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]

View 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)

View 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

Binary file not shown.

View 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
}

View 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.
}
}
}

View 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: &current)
}
}