Swift語(yǔ)言實(shí)現(xiàn)幾個(gè)簡(jiǎn)單算法


隊(duì)列
二分查找
插入排序
歸并排序
快速排序

public struct Stack<T> {
    fileprivate var array: [T] = [T]()
    
    public var isEmpty: Bool {
        return array.isEmpty
    }
    
    public var count: Int {
        return array.count
    }
    
    public mutating func push(_ element: T) {
        array.append(element)
    }
    
    public mutating func pop() -> T? {
        return array.popLast()
    }
    
    public var top: T? {
        return array.last
    }
}

extension Stack: Sequence { //遍歷迭代器
    public func makeIterator() -> AnyIterator<T> {
        var curr = self
        return AnyIterator {
            return curr.pop()
        }
    }
}

隊(duì)列

struct Queue<T> {
    fileprivate var array = [T]()
    
    public var count: Int {
        return array.count
    }
    
    public var isEmpty: Bool {
        return array.isEmpty
    }
    
    public mutating func enqueue(_ element: T) {  // 放入隊(duì)列
        array.append(element)
    }
    
    public mutating func dequeue() -> T? {   // 出隊(duì)列
        if isEmpty  {
            return nil
        }else {
            return array.removeFirst()
        }
    }
    
    public var front: T? {
        return array.first
    }
}

二分查找

二分查找是用于快速查找到目標(biāo)數(shù)據(jù)(已排序)的一種查找方式
通過(guò)取一個(gè)中間值,判斷大小, 然后將最大或最小范圍縮小至當(dāng)前位置, 再次取中間值判斷, 直到取到數(shù)據(jù)

public func binarySearch<T: Comparable>(_ a: [T], key: T) -> Int? {
var lowerBound = 0
var upperBound = a.count
while lowerBound < upperBound {
    let midIndex = lowerBound + (upperBound - lowerBound) / 2 //中間值
    if a[midIndex] == key {
        return midIndex
    } else if a[midIndex] < key {
        lowerBound = midIndex + 1  // 最小值右移
    } else {
        upperBound = midIndex       //最大值左移
    }
}
return nil
}

插入排序

插入排序是遍歷第二位開(kāi)始的每一個(gè)位置上的數(shù)與 之前的數(shù)據(jù)作對(duì)比,符合條件(大于或小于)則與之交換位置, 結(jié)束滿足(位置大于0 && 當(dāng)前數(shù)比之前大或者小)

public func insectionSort<T: Comparable>(_ array: [T], sortdir: (T, T) -> Bool) -> [T] { // sortdir 返回參數(shù)比較 實(shí)現(xiàn)正序倒序 排序
    var a = array

    for x in 1..<array.count {
        var y = x       // y為當(dāng)前位置, 會(huì)依次往前遍歷
        let temp = a[y]
        while y > 0 && sortdir(temp, a[y - 1]) {
            a[y] = a[y - 1]  // 自己等于前面一個(gè)數(shù)
            y -= 1           // 從自己的位置往前遍歷
        }
        a[y] = temp //前面沒(méi)有數(shù)再比自己小了 就放在最前面
    }
    return a
}

歸并排序

歸并排序, 將數(shù)組分割成一個(gè)小數(shù)組元素排序后, 再向上,將已經(jīng)擁有排序的2個(gè)數(shù)組添加到一個(gè)數(shù)組中

func mergeSort(_ arr: [Int]) -> [Int] {
    guard arr.count > 1 else { return arr }
    
    let middlle = arr.count / 2
        let left = mergeSort(Array(arr[0 ..< middlle]))
    let right = mergeSort(Array(arr[middlle ..< arr.count]))
    return merge(left: left, right: right)
}


func merge(left: [Int], right: [Int]) -> [Int] {
    var leftIndex = 0
    var rightIndex = 0
    
    var oright = [Int]() // [1, 2], [3, 4], 遍歷兩個(gè)數(shù)組按照大小組成一個(gè)
    while leftIndex < left.count && rightIndex < right.count {
        if left[leftIndex] < right[rightIndex] {
            oright.append(left[leftIndex])
            leftIndex += 1
        }else if left[leftIndex] > right[rightIndex] {
            oright.append(right[rightIndex])
            rightIndex += 1
        }else {
            oright.append(left[leftIndex])
            leftIndex += 1
            oright.append(right[rightIndex])
            rightIndex += 1
        }
    }
    
    while leftIndex < left.count {   //遍歷 上邊沒(méi)有遍歷完全的  全部加入數(shù)組中
        oright.append(left[leftIndex])
        leftIndex += 1
    }
    
    while rightIndex < right.count {
        oright.append(right[rightIndex])
        rightIndex += 1
    }

    return oright
}

快速排序

通過(guò)將數(shù)組分成三部分: 小于中間值, 等于中間值, 大于中間值, 再將左右兩部分再次分成三段, 返回為: [小于] + [等于] + [大于] 來(lái)完成排序

1.利用swift過(guò)濾函數(shù)實(shí)現(xiàn)的快速排序
func quicksort<T: Comparable>(_ a: [T]) -> [T] {
    guard a.count > 1 else { return a }
    
    let piv = a[a.count/2]
    let les = a.filter{ $0 < piv }
    let gras = a.filter{ $0 > piv}
    let eqs = a.filter{ $0 == piv }
    return quicksort(les) + eqs + gras
}

2.快速排序思想 將目標(biāo)數(shù)組用一個(gè)值將小于這個(gè)值的放在數(shù)組左邊, 大于則放在中間
func quickSockt2<T: Comparable>(_ a: inout [T], low: Int, hgt: Int) -> Int {
    let pov = a[hgt]  //每次都是拿去最后一個(gè)值作為參考值
    
    var i = low // 記錄比參考值小的數(shù)據(jù)最后被換到了哪個(gè)位置
    for j in i...hgt { // 遍歷從低到高的數(shù)組(一個(gè)循環(huán)完成, 數(shù)組的左邊都是比參考值小)
        if a[j] < pov { //如果遍歷值 小于參考值
            (a[i], a[j]) = (a[j], a[i]) // 則將小于參考值的 遍歷值放在i位置,
            i += 1  //x 位置一次相加 //可以標(biāo)記最后一次交換的位置
        }
    }
    (a[i], a[hgt]) = (a[hgt], a[i]) // 將中間值替換為參考值, 參考值最后位置替換成大于她的那個(gè)i值
    return i  // 標(biāo)記了中間值在什么地方
}
    
    
    // 遞歸調(diào)用 通過(guò)將數(shù)組傳下去 分別在對(duì)各自已經(jīng)排序內(nèi)容排序
func quicksortLomuto<T: Comparable>(_ a: inout [T], low: Int, high: Int) {
  if low < high { 
     let p = quickSockt2(&a, low: low, hgt: high) // 將數(shù)組遍歷了一遍  把數(shù)組小于指定參考值值的都放在了左邊,  大于等于的則在數(shù)組的右邊, 并返回了參考值中間位置

      quicksortLomuto(&a, low: low, high: p - 1) // 小于第一次指定參考值的被放在左邊, 這里再重新列為一個(gè)數(shù)組 再次找出指定值, 再實(shí)現(xiàn)分組
      quicksortLomuto(&a, low: p + 1, high: high) // 遞歸調(diào)用到低位置不小與高位置為止
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嵌器,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子谐丢,更是在濱河造成了極大的恐慌爽航,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乾忱,死亡現(xiàn)場(chǎng)離奇詭異讥珍,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)窄瘟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)衷佃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蹄葱,你說(shuō)我怎么就攤上這事氏义。” “怎么了图云?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵惯悠,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我琼稻,道長(zhǎng)吮螺,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任帕翻,我火速辦了婚禮鸠补,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嘀掸。我一直安慰自己紫岩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布睬塌。 她就那樣靜靜地躺著泉蝌,像睡著了一般歇万。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勋陪,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天贪磺,我揣著相機(jī)與錄音,去河邊找鬼诅愚。 笑死寒锚,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的违孝。 我是一名探鬼主播刹前,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼雌桑!你這毒婦竟也來(lái)了喇喉?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤校坑,失蹤者是張志新(化名)和其女友劉穎拣技,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體撒踪,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡过咬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了制妄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掸绞。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖耕捞,靈堂內(nèi)的尸體忽然破棺而出衔掸,到底是詐尸還是另有隱情,我是刑警寧澤俺抽,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布敞映,位于F島的核電站,受9級(jí)特大地震影響磷斧,放射性物質(zhì)發(fā)生泄漏振愿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一弛饭、第九天 我趴在偏房一處隱蔽的房頂上張望冕末。 院中可真熱鬧,春花似錦侣颂、人聲如沸档桃。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)藻肄。三九已至蔑舞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嘹屯,已是汗流浹背攻询。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抚垄,地道東北人蜕窿。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓谋逻,卻偏偏與公主長(zhǎng)得像呆馁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子毁兆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354