亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Swift實現堆排序算法的代碼示例

 更新時間:2016年06月08日 11:38:54   作者:黃儀標  
堆排序(HeapSort)是一樹形選擇排序,堆排序的時間復雜度O(nlogn),這里我們來看一下Swift實現基堆排序算法的代碼示例,首先對堆排序算法的基本概念作一個了解:

算法思想
堆排序利用了最大堆(或小根堆)堆頂記錄的關鍵字最大(或最小)這一特征,使得在當前無序區(qū)中選取最大(或最?。╆P鍵字的記錄變得簡單。
1.用最大堆排序的基本思想
(1)先將初始文件R[1..n]建成一個最大堆,此堆為初始的無序區(qū)
(2)再將關鍵字最大的記錄R[1](即堆頂)和無序區(qū)的最后一個記錄R[n]交換,由此得到新的無序區(qū)R[1..n-1]和有序區(qū)R[n],且滿足R[1..n-1].keys≤R[n].key
(3)由于交換后新的根R[1]可能違反堆性質,故應將當前無序區(qū)R[1..n-1]調整為堆。然后再次將R[1..n-1]中關鍵字最大的記錄R[1]和該區(qū)間的最后一個記錄R[n-1]交換,由此得到新的無序區(qū)R[1..n-2]和有序區(qū)R[n-1..n],且仍滿足關系R[1..n-2].keys≤R[n-1..n].keys,同樣要將R[1..n-2]調整為堆。
……
直到無序區(qū)只有一個元素為止。
2.最大堆排序算法的基本操作:
(1)建堆,建堆是不斷調整堆的過程,從len/2處開始調整,一直到第一個節(jié)點,此處len是堆中元素的個數。建堆的過程是線性的過程,從len/2到0處一直調用調整堆的過程,相當于o(h1)+o(h2)…+o(hlen/2) 其中h表示節(jié)點的深度,len/2表示節(jié)點的個數,這是一個求和的過程,結果是線性的O(n)。
(2)調整堆:調整堆在構建堆的過程中會用到,而且在堆排序過程中也會用到。利用的思想是比較節(jié)點i和它的孩子節(jié)點left(i),right(i),選出三者最大(或者最小)者,如果最大(?。┲挡皇枪?jié)點i而是它的一個孩子節(jié)點,那邊交互節(jié)點i和該節(jié)點,然后再調用調整堆過程,這是一個遞歸的過程。調整堆的過程時間復雜度與堆的深度有關系,是lgn的操作,因為是沿著深度方向進行調整的。
(3)堆排序:堆排序是利用上面的兩個過程來進行的。首先是根據元素構建堆。然后將堆的根節(jié)點取出(一般是與最后一個節(jié)點進行交換),將前面len-1個節(jié)點繼續(xù)進行堆調整的過程,然后再將根節(jié)點取出,這樣一直到所有節(jié)點都取出。堆排序過程的時間復雜度是O(nlgn)。因為建堆的時間復雜度是O(n)(調用一次);調整堆的時間復雜度是lgn,調用了n-1次,所以堆排序的時間復雜度是O(nlgn)[2]
注意
(1)只需做n-1趟排序,選出較大的n-1個關鍵字即可以使得文件遞增有序。
(2)用小根堆排序與利用最大堆類似,只不過其排序結果是遞減有序的。堆排序和直接選擇排序相反:在任何時刻堆排序中無序區(qū)總是在有序區(qū)之前,且有序區(qū)是在原向量的尾部由后往前逐步擴大至整個向量為止

Swift示例
(1)基于最大堆實現升序排序

func initHeap(inout a: [Int]) {
 for var i = (a.count - 1) / 2; i >= 0; --i {
  adjustMaxHeap(&a, len: a.count, parentNodeIndex: i)
 }
}
 
func adjustMaxHeap(inout a: [Int], len: Int, parentNodeIndex: Int) {
 // 如果len <= 0,說明已經無序區(qū)已經縮小到0
 guard len > 1 else {
  return
 }
 
 // 父結點的左、右孩子的索引
 let leftChildIndex = 2 * parentNodeIndex + 1
 
 // 如果連左孩子都沒有, 一定沒有右孩子,說明已經不用再往下了
 guard leftChildIndex < len else {
  return
 }
 
 let rightChildIndex = 2 * parentNodeIndex + 2
 
 // 用于記錄需要與父結點交換的孩子的索引
 var targetIndex = -1
 
 // 若沒有右孩子,但有左孩子,只能選擇左孩子
 if rightChildIndex > len {
  targetIndex = leftChildIndex
 } else {
  // 左、右孩子都有,則需要找出最大的一個
  targetIndex = a[leftChildIndex] > a[rightChildIndex] ? leftChildIndex : rightChildIndex
 }
 
 // 只有孩子比父結點還要大,再需要交換
 if a[targetIndex] > a[parentNodeIndex] {
  let temp = a[targetIndex]
  
  a[targetIndex] = a[parentNodeIndex]
  a[parentNodeIndex] = temp
  
  // 由于交換后,可能會破壞掉新的子樹堆的性質,因此需要調整以a[targetIndex]為父結點的子樹,使之滿足堆的性質
  adjustMaxHeap(&a, len: len, parentNodeIndex: targetIndex)
 }
}
 
func maxHeapSort(inout a: [Int]) {
 guard a.count > 1 else {
  return
 }
 
 initHeap(&a)
 
 for var i = a.count - 1; i > 0; --i {
  // 每一趟都將堆頂交換到指定范圍內的最后一個位置
  if a[0] > a[i] {
   let temp = a[0]
   
   a[0] = a[i]
   a[i] = temp
  }
  print(a)
  print(i - 1)
  // 有序區(qū)長度+1,而無序區(qū)長度-1,繼續(xù)縮小無序區(qū),所以i-1
  // 堆頂永遠是在0號位置,所以父結點調整從堆頂開始就可以了
  adjustMaxHeap(&a, len: i - 1, parentNodeIndex: 0)
  print(a)
 }
}

 
(2)基于最小堆降序排序

func initHeap(inout a: [Int]) {
 for var i = (a.count - 1) / 2; i >= 0; --i {
  adjustMinHeap(&a, len: a.count, parentNodeIndex: i)
 }
}
 
func adjustMinHeap(inout a: [Int], len: Int, parentNodeIndex: Int) {
 // 如果len <= 0,說明已經無序區(qū)已經縮小到0
 guard len > 1 else {
  return
 }
 
 // 父結點的左、右孩子的索引
 let leftChildIndex = 2 * parentNodeIndex + 1
 
 // 如果連左孩子都沒有, 一定沒有右孩子,說明已經不用再往下了
 guard leftChildIndex < len else {
  return
 }
 
 let rightChildIndex = 2 * parentNodeIndex + 2
 
 // 用于記錄需要與父結點交換的孩子的索引
 var targetIndex = -1
 
 // 若沒有右孩子,但有左孩子,只能選擇左孩子
 if rightChildIndex > len {
  targetIndex = leftChildIndex
 } else {
  // 左、右孩子都有,則需要找出最大的一個
  targetIndex = a[leftChildIndex] < a[rightChildIndex] ? leftChildIndex : rightChildIndex
 }
 
 // 只有孩子比父結點還要大,再需要交換
 if a[targetIndex] < a[parentNodeIndex] {
  let temp = a[targetIndex]
  
  a[targetIndex] = a[parentNodeIndex]
  a[parentNodeIndex] = temp
  
  // 由于交換后,可能會破壞掉新的子樹堆的性質,因此需要調整以a[targetIndex]為父結點的子樹,使之滿足堆的性質
  adjustMinHeap(&a, len: len, parentNodeIndex: targetIndex)
 }
}
 
func minHeapSort(inout a: [Int]) {
 guard a.count > 1 else {
  return
 }
 
 initHeap(&a)
 
 for var i = a.count - 1; i > 0; --i {
  // 每一趟都將堆頂交換到指定范圍內的最后一個位置
  if a[0] < a[i] {
   let temp = a[0]
   
   a[0] = a[i]
   a[i] = temp
  } else {
    return // 可以直接退出了,因為已經全部有序了
  }
  
  // 有序區(qū)長度+1,而無序區(qū)長度-1,繼續(xù)縮小無序區(qū),所以i-1
  // 堆頂永遠是在0號位置,所以父結點調整從堆頂開始就可以了
  adjustMinHeap(&a, len: i - 1, parentNodeIndex: 0)
 }
}

測試:

var arr = [5, 3, 8, 6, 4]
//var arr = [89,-7,999,-89,7,0,-888,7,-7]
maxHeapSort(&arr)
 
print(arr)
 
// 打印日志如下:
[4, 6, 5, 3, 8]
3
[6, 4, 5, 3, 8]
 
[3, 4, 5, 6, 8]
2
[5, 4, 3, 6, 8]
 
[3, 4, 5, 6, 8]
1
[3, 4, 5, 6, 8]
 
[3, 4, 5, 6, 8]
0
[3, 4, 5, 6, 8]
 
[3, 4, 5, 6, 8]

相關文章

  • RxSwift發(fā)送及訂閱 Subjects、Variables代碼示例

    RxSwift發(fā)送及訂閱 Subjects、Variables代碼示例

    這篇文章主要介紹了RxSwift發(fā)送及訂閱 Subjects、Variables代碼示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12
  • Swift教程之函數詳解

    Swift教程之函數詳解

    這篇文章主要介紹了Swift教程之函數詳解,本文講解了函數的聲明與調用、函數的參數和返回值、函數參數名、函數類型等內容,需要的朋友可以參考下
    2015-01-01
  • Swift UILable 設置內邊距實例代碼

    Swift UILable 設置內邊距實例代碼

    本文主要介紹Swift UILable 設置內邊距,這里提供示例代碼供大家參考,有需要的小伙伴可以看下
    2016-07-07
  • Swift?Error重構的基礎示例詳解

    Swift?Error重構的基礎示例詳解

    這篇文章主要為大家介紹了Swift?Error基礎錯誤處理的方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Swift 4.2使用self做為變量名淺析

    Swift 4.2使用self做為變量名淺析

    這篇文章主要給大家介紹了關于Swift 4.2使用self做為變量名的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-09-09
  • swift自定義表格控件(UITableView)

    swift自定義表格控件(UITableView)

    這篇文章主要為大家詳細介紹了swift自定義表格控件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Swift仿選擇電影票的效果并實現無限/自動輪播的方法

    Swift仿選擇電影票的效果并實現無限/自動輪播的方法

    這篇文章主要給大家介紹了關于Swift仿選擇電影票的效果并實現無限/自動輪播的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-08-08
  • swift3.0鍵盤彈起遮擋輸入框問題的解決方案

    swift3.0鍵盤彈起遮擋輸入框問題的解決方案

    這篇文章主要介紹了swift3.0鍵盤彈起遮擋輸入框問題的解決方案,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-11-11
  • 通過示例分析Swift單例模式

    通過示例分析Swift單例模式

    這篇文章主要介紹了通過示例分析Swift單例模式的三種方法,分別是全局變量,內部變量,dispatch_once方式,有需要的小伙伴可以參考下。
    2015-06-06
  • Swift協(xié)議Protocol介紹

    Swift協(xié)議Protocol介紹

    協(xié)議規(guī)定了用來實現某一特定功能所必需的方法和屬性。任意能夠滿足協(xié)議要求的類型被稱為遵循(conform)這個協(xié)議。類,結構體或枚舉類型都可以遵循協(xié)議,并提供具體實現來完成協(xié)議定義的方法和功能
    2022-08-08

最新評論