比较排序算法的简单复习(说明+代码)

前面看到有人发了数组排序的代码,想起自己前阵子为了应付xxxxxx公司笔试复习时写下的一些关于比较排序算法 的笔记和代码,拿出来和大家分享一下,攒点RP:

(代码基本是按照《算法导论》的伪代码写的,lgn是以2为底的,西塔估计打不出,我这里都用O了)

1、Insertion Sort

遍历数组,将小的值插在前面。

原地、 稳定 的排序算法。复杂度O(n^2)

  1. a = [5,2,4,6,1,3]
  2. p a

  3. for j in 1...a.size
  4.     key = a[j]
  5.     i = j - 1
  6.     while i >=0 and a[i] > key
  7.         a[i + 1] = a[i]
  8.         i -= 1
  9.     end
  10.     a[i + 1] = key
  11. end

  12. p a
2、Merge Sort

递归排序A[1..n/2] A[n/2+1..n],然后合并两端已排序序列,当n=1时排序完成。

非原地、非稳定 的排序算法。复杂度O(nlgn)

  1. def merge (arr, s, mid, e)
  2.     n1 = mid - s + 1
  3.     n2 = e - mid
  4.     
  5.     left = arr[s..mid]
  6.     right = arr[mid + 1..e]
  7.     
  8.     i = j = 0
  9.     for index in s..e
  10.         if i < n1 and j < n2
  11.             if left[i] < right[j]
  12.                 arr[index] = left[i]
  13.                 i += 1
  14.             else
  15.                 arr[index] = right[j]
  16.                 j += 1
  17.             end
  18.         else
  19.             arr[index..e] = left[i...n1] if i < n1
  20.             arr[index..e] = right[j...n2] if j < n2
  21.         end
  22.     end
  23. end

  24. def merge_sort(arr, s, e)
  25.     if s < e
  26.         mid = (s + e) / 2
  27.         merge_sort arr, s, mid
  28.         merge_sort arr, mid + 1, e
  29.         merge arr, s, mid, e
  30.     end
  31. end

  32. a = [5,2,4,6,1,3]
  33. p a
  34. merge_sort a, 0, a.size - 1
  35. p a
3、Quick Sort

将数组A[p..r]分成A[p..q-1]和A[q+1..r](可能有空数组),前者小于A[q],后者大于A[q];对两个数组分别进行Quick Sort。

原地、非稳定 的排序算法,最坏运行时间O(n^2),平均运行时间O(nlgn)。

  1. def partition arr, start_index, end_index
  2.     x = arr[end_index]
  3.     i = start_index
  4.     
  5.     (start_index...end_index).each do |j|
  6.         if arr[j] <= x
  7.             arr[j], arr[i] = arr[i], arr[j]
  8.             i += 1
  9.         end
  10.     end
  11.     arr[i], arr[end_index] = arr[end_index], arr[i]
  12.     p arr
  13.     i
  14. end
  15. def quick_sort arr, start_index, end_index
  16.     if start_index < end_index
  17.         pivot = partition arr, start_index, end_index
  18.         quick_sort arr, start_index, pivot - 1
  19.         quick_sort arr, pivot + 1, end_index
  20.     end
  21. end
  22. a = [5,2,4,6,1,3]
  23. p a
  24. quick_sort a, 0, a.size - 1
  25. p a
4、Heap Sort

堆可以被看作一棵完全二叉树;数组表示时,结点i,parent为[i/2],left为2i,right为2i+1;长度为n的数组表示堆, [n/2]+1到n都为叶结点。([]表示取下底)

堆排序使用最大堆,先构建最大堆,取出堆顶元素放在最后,堆的元素数减1,维护最大堆性质,再取出堆顶元素,直至完全排序。

原地、非稳定 的排序算法,MAX_HEAPFIER时间为O(lgn),BUILD_MAX_HEAP为O(n),HEAP_SORT为O(nlogn)。

  1. def max_heapfier arr, root_index, heap_size
  2.     left_index = root_index * 2
  3.     right_index = left_index + 1
  4.     max_index = root_index
  5.     max_index = left_index if left_index < heap_size && arr[left_index] > arr[root_index]
  6.     max_index = right_index if right_index < heap_size && arr[right_index] > arr[max_index]
  7.     unless max_index == root_index
  8.         arr[root_index], arr[max_index] = arr[max_index], arr[root_index]
  9.         max_heapfier arr, max_index, heap_size
  10.     end
  11. end

  12. def build_max_heap arr, root_index, heap_size
  13.     (heap_size / 2).downto(0) { |i| max_heapfier arr, i, heap_size}
  14. end

  15. def heap_sort arr
  16.     build_max_heap arr, 0, arr.size
  17.     heap_size = arr.size
  18.     (heap_size - 1).downto(1) do |i|
  19.         arr[0], arr[i] = arr[i], arr[0]
  20.         heap_size -= 1
  21.         max_heapfier arr, 0, heap_size
  22.     end
  23. end

  24. a = [5,2,4,6,1,3]
  25. p a
  26. heap_sort a
  27. p a
5、Selection Sort

遍历数组,每次取出最小的元素。

原地、稳定 的排序算法,复杂度O(n^2)。

  1. def get_min(arr, b, e)
  2.     min_index = b
  3.     for i in b..e
  4.         min_index = i if arr[i] < arr[min_index]
  5.     end
  6.     min_index
  7. end

  8. a = [5,2,4,6,1,3]
  9. p a
  10. for i in 0...a.size
  11.     index = get_min a, i, a.size - 1
  12.     a[i], a[index] = a[index], a[i]
  13. end
  14. p a
6、Bubble Sort

遍历数组,邻近的两两比较,小的放前面,直到最小的移到最前面,重复这个过程,直至排序完毕。

原地、稳定 的排序算法,复杂度O(n^2)。

  1. def bubble_sort arr
  2.   (0...arr.size).each do |i|
  3.     (arr.size - 1).downto i do |j|
  4.       arr[j], arr[j - 1] = arr[j - 1], arr[j] if arr[j] < arr[j - 1]
  5.     end
  6.   end
  7. end

  8. a = [5,2,4,6,1,3]
  9. p a
  10. bubble_sort a
  11. p a
(5出现在习题里,6书上没有讲,都比较简单)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值