快速稳定排序?

Posted

技术标签:

【中文标题】快速稳定排序?【英文标题】:Swift Stable Sort? 【发布时间】:2015-06-02 01:22:59 【问题描述】:

此时(2015 年 3 月 28 日):如果我想在 swift 中使用稳定排序,我必须使用 NSArraysortWithOptions 或者在 Swift 中编写自己的稳定排序,例如 insertion sort?我在Apple Swift docs 中看到sorted 不稳定。

Example of stable sort in NSMutableArray:

[array sortWithOptions:NSSortStable usingComparator:^NSComparisonResult(id obj1, id obj2) 
    return [obj1 compare:obj2];
];

除了使用 Objective-C 或编写我自己的排序之外,我是否错过了在 Swift 中可用的另一个选项?

【问题讨论】:

是的..你也可以编写一个调用objective-c函数的swift-wrapper——如果还没有的话.. 当然!我脑子里放了个屁。把它作为一个答案,我会用绿色复选标记 @Michael 。 :) 这能回答你的问题吗? How to stable sort an array in swift? 【参考方案1】:

除了您的 Swift 包装器方法之外,您还可以使用 C mergesort: 函数

var array2 = ["mango", "apple", "pear", "apple", "orange", "banana"]
mergesort(&array2, array2.count, MemoryLayout<String>.size, 
    let a = $0.unsafelyUnwrapped.load(as:String.self)
    let b = $1.unsafelyUnwrapped.load(as:String.self)
    if a == b 
        return 0
    
    else if a < b 
        return -1 
    else 
        return 1
    
)
print(array2) // ["apple", "apple", "banana", "mango", "orange", "pear"]

或者编写一个 Pure Swift 方法,让事情变得更通用:

var array = ["mango", "apple", "pear", "banana", "orange", "apple", "banana"]

enum SortType 
    case Ascending
    case Descending


struct SortObject<T> 
    let value:T
    let startPosition:Int
    var sortedPosition:Int?


func swiftStableSort<T:Comparable>(array:inout [T], sortType:SortType = .Ascending) 

    var sortObjectArray = array.enumerated().mapSortObject<T>(value:$0.element, startPosition:$0.offset, sortedPosition:nil)

    for s in sortObjectArray 
        var offset = 0
        for x in array[0..<s.startPosition]  
            if s.value < x 
                offset += sortType == .Ascending ? -1 : 0
            
            else if s.value > x 
                offset += sortType == .Ascending ? 0 : -1
            
        

        for x in array[s.startPosition+1..<array.endIndex]  
            if s.value > x  
                offset += sortType == .Ascending ? 1 : 0
            
            else if s.value < x  
                offset += sortType == .Ascending ? 0 : 1
            
        
        sortObjectArray[s.startPosition].sortedPosition = offset + s.startPosition
    

    for s in sortObjectArray 
        if let sInd = s.sortedPosition 
            array[sInd] = s.value
        
    



swiftStableSort(array: &array, sortType:.Ascending) // ["apple", "apple", "banana", "banana", "mango", "orange", "pear"]
swiftStableSort(array: &array, sortType:.Descending) // ["pear", "orange", "mango", "banana", "banana", "apple", "apple"]

(这是我谦虚直接的做法,其他人可以优化。)

【讨论】:

以上是关于快速稳定排序?的主要内容,如果未能解决你的问题,请参考以下文章

微妙的快速排序稳定性问题

2golang之快速排序

快速排序不能变成稳定排序吗?

快速排序堆排序归并排序比较

快速排序

快速排序