双向链表的快速排序(swift版本)

面试经常会被问到的单向链表的快速排序or双向链表的快速排序,现在用swift写了一个双向链表的快速排序,直接上代码
获取源码

//初始化
var linkList = LinkList<Int>()
linkList.append(value: 12)
linkList.append(value: 5)
linkList.append(value: 30)
linkList.append(value: 3)
linkList.append(value: 3)
linkList.append(value: 2)
linkList.append(value: 9)
linkList.append(value: 4)
linkList.append(value: 11)
linkList.append(value: 19)
linkList.append(value: 15)
linkList.append(value: 16)

print("Init Data: \(linkList)")

var firstNode = linkList.searchIndex(index: 0)
var endNode = linkList.searchIndex(index: linkList.linkListSize() - 1)
quickSort(linkList: &linkList, low: &firstNode, high: &endNode)

print("After QuickSort: \(linkList)")
// Print效果
Init Data: [Optional(12), Optional(5), Optional(30), Optional(3), Optional(3), Optional(2), Optional(9), Optional(4), Optional(11), Optional(19), Optional(15), Optional(16)]
After QuickSort: [Optional(2), Optional(3), Optional(3), Optional(4), Optional(5), Optional(9), Optional(11), Optional(12), Optional(15), Optional(16), Optional(19), Optional(30)]
Program ended with exit code: 0
class Node<T> {
    var value: T
    var next: Node?
    weak var previous: Node?

    init(value: T) {
        self.value = value
    }
}
class LinkList<T: Comparable> {
    var head: Node<T>?
    var tail: Node<T>?
    
    // Add
    func append(value: T) {
        let newNode = Node.init(value: value)
        if let tailNode = tail {
            newNode.previous = tailNode
            tailNode.next = newNode
        }
        else {
            head = newNode
        }
        tail = newNode
    }
    
    // Size
    func linkListSize() -> Int {
        if let node = head {
            var index = 1
            var node = node.next
            while node != nil {
                index += 1
                node = node?.next
            }
            return index
        }
        else {
            return 0
        }
    }
    
    // Search
    func searchNode(indexNode: Node<T>) -> Int {
        if let node = head {
            if node === indexNode {
                return 0
            }
            else {
                var index: Int = 0
                var node = node.next
                while node != nil {
                    index += 1
                    if node === indexNode {
                        return index
                    }
                    node = node?.next
                }
                // 不存在返回-1
                return -1
            }

        }
        else {
            // 不存在返回-1
            return -1
        }
    }
    
    func lowBeforeHigh(low: Node<T>, high: Node<T>) -> Bool {
        if low === high {
            return false
        }
        else {
            var node = low.next
            while node != nil {
                if node === high {
                    return true
                }
                node = node?.next
            }
        }
        return false
    }
    
    func searchIndex(index: Int) -> Node<T>? {
        if let node = head {
            if index == 0 {
                return node
            }
            else {
                var node = node.next
                var nodeIndex: Int = 1
                while node != nil {
                    if nodeIndex == index {
                        return node
                    }
                    nodeIndex += 1
                    node = node?.next
                }
                return nil
            }
        }
        else {
            return nil
        }
    }
    
    // Remove
    func remove(node: Node<T>) -> T {
        let preNode = node.previous
        let nextNode = node.next
        
        if let preNode = preNode {
            // 前节点存在
            preNode.next = nextNode
        }
        else {
            // 不存在前节点,将nextNode置成head
            head = nextNode
        }
        nextNode?.previous = preNode
        
        if nextNode == nil {
            tail = preNode
        }
        
        // 将node置成nil
        node.previous = nil
        node.next = nil
        return node.value
    }
    
    func removeAll() {
        head = nil
        tail = nil
    }
}
//MARK: - QuickSort
func quickSort(linkList: inout LinkList<Int>, low: inout Node<Int>?, high: inout Node<Int>?) {
    guard linkList.head != nil && linkList.tail != nil else {
        return
    }
    guard low != nil && high != nil else {
        return
    }
    guard linkList.lowBeforeHigh(low: low!, high: high!) else {
        return
    }
    
    let midIndex = partition(linkList: &linkList, low: &low!, high: &high!)
    // 递归
    quickSort(linkList: &linkList, low: &low, high: &linkList.searchIndex(index: midIndex )!.previous)
    quickSort(linkList: &linkList, low: &linkList.searchIndex(index: midIndex)!.next, high: &high)
}

func partition(linkList: inout LinkList<Int>, low: inout Node<Int>, high: inout Node<Int>) -> Int {
    var value: Int = 0
    var lowNode = low
    var highNode = high
    let lowValue = low.value
    
    while linkList.lowBeforeHigh(low: lowNode, high: highNode) {
        // 从右边向左边扫描
        while linkList.lowBeforeHigh(low: lowNode, high: highNode) && highNode.value >= lowValue {
            highNode = highNode.previous!
        }

        if highNode === lowNode {
            value = linkList.searchNode(indexNode: lowNode)
            break
        }
        
        // lowNode和highNode交换值
        let temp1Value = lowNode.value
        lowNode.value = highNode.value
        highNode.value = temp1Value
        
        // 从左边向右边扫描
        while linkList.lowBeforeHigh(low: lowNode, high: highNode) && lowNode.value <= lowValue {
            lowNode = lowNode.next!
        }
        if lowNode === highNode {
            value = linkList.searchNode(indexNode: lowNode)
            break
        }
        // lowNode和highNode交换值
        let temp2Value = lowNode.value
        lowNode.value = highNode.value
        highNode.value = temp2Value
    }
    return value
}

func swapTwoNode(low: inout Node<Int>, high: inout Node<Int>) {
    // 相邻节点
    if low.next === high {
        low.previous?.next = high
        high.previous = low.previous
        
        low.previous = high
        low.next = high.next
        
        high.next?.previous = low
        high.next = low
    }
    else {
        // 非相邻节点
        low.previous?.next = high
        low.next?.previous = high
        
        high.next?.previous = low
        high.previous?.next = low
        
        let temp1 = low.previous
        low.previous = high.previous
        high.previous = temp1
        
        let temp2 = low.next
        low.next = high.next
        high.next = temp2
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,204评论 25 708
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,229评论 4 61
  • 远程控制的重要性不必多说,而越来越多的程序猿和设计狮们也开始使用Mac电脑,那么如何用Mac电脑远程控制Windo...
    LeoLeeYEAH阅读 103,416评论 9 10
  • 雨过天晴,夕阳层林尽染,鸟儿归巢隐形 童年里 一朵花儿在洪流里绽放,在洪流里凋谢….. 绽放时,昙花一现 凋谢时,...
    北国小哥阅读 353评论 0 1
  • 一直以为平常心 有些东西就不会散场 不辜负也会受伤的道理 后来才领悟 郊区 风景区 学府校区 秒杀四年光阴 似是故...
    码字后生阅读 540评论 0 2