Swift 算法实现之链表

2,121 阅读3分钟

一、概述

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。

本文将用Swift去实现链表的增删改查:

(1)查找链表:按序号查找、按值查找定位

(2)插入结点

(3)删除结点

(4)修改结点

 

二、实现思路及代码

首先先定义一下链表结点的数据结构:

class LinkList {
    
    var value: Int
    var next: LinkList?
    init(_ val: Int) {
        value = val
    }

}

对于链表的查找,其实很简单,无外乎就是链表的遍历,所以不做过多描述,直接上代码。下面两个查找(按序号查找、按值查找定位)算法时间复杂度都为O(n)

 

1、查找链表

(1)按序号查找

//1、按序号查找:查找第index位置上的结点
func getLinkList(_ linkList:LinkList,_ index:Int)->LinkList?{
    
    var linkList = linkList
    var tempIndex = 0
    
    while linkList.next != nil && tempIndex < index {
        linkList = linkList.next!
        tempIndex += 1
    }
    
    if tempIndex == index {
        return linkList
    }else{
        return nil
    }
    
}

 

(2)按值查找定位

//2、按值查找定位:获取指定value值的结点在链表中的位置
func locLinkList(_ linkList:LinkList,_ value:Int)->Int?{
    
    var linkList = linkList
    var tempIndex = 0
    
    while linkList.value != value && linkList.next != nil{
        linkList = linkList.next!
        tempIndex += 1
    }
    
    if linkList.value == value {
        return tempIndex
    }else{
        return nil
    }
    
}

 

2、插入结点

想要在index位置插入结点,首先就要拿到index位置结点的前驱结点,然后通过改变结点的next值去实现结点的插入,如下图:

Snip20170322_1

算法实现如下:

//插入结点:在index位置插入指定value值的结点
func insertLinkList(_ linkList:LinkList,_ value:Int,_ index:Int)->LinkList?{
    
    let pNode = getLinkList(linkList,index-1)
    if pNode != nil {
        let newNode = LinkList(value)
        newNode.next = pNode?.next
        pNode?.next = newNode
        return linkList
    }else{
        return nil
    }
    
}

 

3、删除结点

删除结点的原理和插入结点类似,也是拿到index位置结点的前驱结点,然后重置该前驱结点的next值为要删除结点的后一个结点,如下图:

Snip20170322_2

算法实现如下:

//删除结点:删除index位置的结点
func delLinkList(_ linkList:LinkList,_ index:Int)->LinkList?{
    
    //如果是头结点,则直接返回头结点的下一个结点
    if index == 0 {
        return linkList.next
    }
    
    //先拿到要删除的结点的上一个结点
    let pNode = getLinkList(linkList, index-1)
    //不存在index位置结点直接return nil
    if pNode?.next == nil {
        print("不存在index位置结点!")
        return nil
    }
    pNode?.next = pNode?.next?.next
    
    return linkList
}

 

4、修改结点

修改结点要比插入、删除简单一点,只要拿到该结点然后修改其value值即可。

算法实现如下:

//修改结点:修改index位置的结点
func updateLinkList(_ linkList:LinkList,_ index:Int,_ newValue:Int)->LinkList?{

    let pNode = getLinkList(linkList, index)
    pNode?.value = newValue
    
    return linkList
}

 

以上就是用Swift实现的链表的增删改查,大家如果感兴趣可以试着实现删除指定value值的结点和修改指定value值的结点算法。

原创文章,转载请注明: 转载自李峰峰博客

本文链接地址: Swift算法实现之链表