访问次数
我的另一个总结性博客: todototry 大米粒

各种排序算法 ruby 版本

Θ(n^2) 

1, Bubble sort 

Ruby代码  收藏代码
  1. def bubble_sort(a)  
  2.   (a.size-2).downto(0) do |i|  
  3.     (0..i).each do |j|  
  4.       a[j], a[j+1] = a[j+1], a[j] if a[j] > a[j+1]  
  5.     end  
  6.   end  
  7.   return a  
  8. end  



2, Selection sort 

Ruby代码  收藏代码
  1. def selection_sort(a)  
  2.   b = []  
  3.   a.size.times do |i|  
  4.     min = a.min  
  5.     b << min  
  6.     a.delete_at(a.index(min))  
  7.   end  
  8.   return b  
  9. end  



3, Insertion sort 

Ruby代码  收藏代码
  1. def insertion_sort(a)  
  2.   a.each_with_index do |el,i|  
  3.     j = i - 1  
  4.       while j >= 0  
  5.         break if a[j] <= el  
  6.         a[j + 1] = a[j]  
  7.         j -= 1  
  8.       end  
  9.     a[j + 1] = el  
  10.   end  
  11.   return a  
  12. end  



4, Shell sort 

Ruby代码  收藏代码
  1. def shell_sort(a)  
  2.   gap = a.size  
  3.   while(gap > 1)  
  4.     gap = gap / 2  
  5.     (gap..a.size-1).each do |i|  
  6.       j = i  
  7.       while(j > 0)  
  8.         a[j], a[j-gap] = a[j-gap], a[j] if a[j] <= a[j-gap]  
  9.         j = j - gap  
  10.       end  
  11.     end  
  12.   end  
  13.   return a  
  14. end  



Θ(n*logn) 

1, Merge sort 

Ruby代码  收藏代码
  1. def merge(l, r)  
  2.   result = []  
  3.   while l.size > 0 and r.size > 0 do  
  4.     if l.first < r.first  
  5.       result << l.shift  
  6.     else  
  7.       result << r.shift  
  8.     end  
  9.   end  
  10.   if l.size > 0  
  11.     result += l  
  12.   end  
  13.   if r.size > 0  
  14.     result += r  
  15.   end  
  16.   return result  
  17. end  
  18.   
  19. def merge_sort(a)  
  20.   return a if a.size <= 1  
  21.   middle = a.size / 2  
  22.   left = merge_sort(a[0, middle])  
  23.   right = merge_sort(a[middle, a.size - middle])  
  24.   merge(left, right)  
  25. end  



2, Heap sort 

Ruby代码  收藏代码
  1. def heapify(a, idx, size)  
  2.   left_idx = 2 * idx + 1  
  3.   right_idx = 2 * idx + 2  
  4.   bigger_idx = idx  
  5.   bigger_idx = left_idx if left_idx < size && a[left_idx] > a[idx]  
  6.   bigger_idx = right_idx if right_idx < size && a[right_idx] > a[bigger_idx]  
  7.   if bigger_idx != idx  
  8.     a[idx], a[bigger_idx] = a[bigger_idx], a[idx]  
  9.     heapify(a, bigger_idx, size)  
  10.   end  
  11. end  
  12.   
  13. def build_heap(a)  
  14.   last_parent_idx = a.length / 2 - 1  
  15.   i = last_parent_idx  
  16.   while i >= 0  
  17.     heapify(a, i, a.size)  
  18.     i = i - 1  
  19.   end  
  20. end  
  21.   
  22. def heap_sort(a)  
  23.   return a if a.size <= 1  
  24.   size = a.size  
  25.   build_heap(a)  
  26.   while size > 0  
  27.     a[0], a[size-1] = a[size-1], a[0]  
  28.     size = size - 1  
  29.     heapify(a, 0, size)  
  30.   end  
  31.   return a  
  32. end  



3, Quick sort 

Ruby代码  收藏代码
  1. def quick_sort(a)  
  2.   (x=a.pop) ? quick_sort(a.select{|i| i <= x}) + [x] + quick_sort(a.select{|i| i > x}) : []  
  3. end  



Θ(n) 

1, Counting sort 

Ruby代码  收藏代码
  1. def counting_sort(a)  
  2.   min = a.min  
  3.   max = a.max  
  4.   counts = Array.new(max-min+1, 0)  
  5.   
  6.   a.each do |n|  
  7.     counts[n-min] += 1  
  8.   end  
  9.   
  10.   (0...counts.size).map{|i| [i+min]*counts[i]}.flatten  
  11. end  



2, Radix sort 

Ruby代码  收藏代码
  1. def kth_digit(n, i)  
  2.   while(i > 1)  
  3.     n = n / 10  
  4.     i = i - 1  
  5.   end  
  6.   n % 10  
  7. end  
  8.   
  9. def radix_sort(a)  
  10.   max = a.max  
  11.   d = Math.log10(max).floor + 1  
  12.   
  13.   (1..d).each do |i|  
  14.     tmp = []  
  15.     (0..9).each do |j|  
  16.       tmp[j] = []  
  17.     end  
  18.   
  19.     a.each do |n|  
  20.       kth = kth_digit(n, i)  
  21.       tmp[kth] << n  
  22.     end  
  23.     a = tmp.flatten  
  24.   end  
  25.   return a  
  26. end  



3, Bucket sort 

Ruby代码  收藏代码
  1. def quick_sort(a)  
  2.   (x=a.pop) ? quick_sort(a.select{|i| i <= x}) + [x] + quick_sort(a.select{|i| i > x}) : []  
  3. end  
  4.   
  5. def first_number(n)  
  6.   (n * 10).to_i  
  7. end  
  8.   
  9. def bucket_sort(a)  
  10.   tmp = []  
  11.   (0..9).each do |j|  
  12.     tmp[j] = []  
  13.   end  
  14.     
  15.   a.each do |n|  
  16.     k = first_number(n)  
  17.     tmp[k] << n  
  18.   end  
  19.   
  20.   (0..9).each do |j|  
  21.     tmp[j] = quick_sort(tmp[j])  
  22.   end  
  23.   
  24.   tmp.flatten  
  25. end  
  26.   
  27. a = [0.75, 0.13, 0, 0.44, 0.55, 0.01, 0.98, 0.1234567]  
  28. p bucket_sort(a)  
  29.   
  30. # Result:   
  31. [0, 0.01, 0.1234567, 0.13, 0.44, 0.55, 0.75, 0.98]  

github 上 的另一个 实现


Ruby代码  收藏代码
  1. require 'containers/heap' # for heapsort  
  2.    
  3. =begin rdoc  
  4. This module implements sorting algorithms. Documentation is provided for each algorithm.  
  5. =end  
  6. module Algorithms::Sort  
  7.   # Bubble sort: A very naive sort that keeps swapping elements until the container is sorted.  
  8.   # Requirements: Needs to be able to compare elements with <=>, and the [] []= methods should  
  9.   # be implemented for the container.  
  10.   # Time Complexity: О(n^2)  
  11.   # Space Complexity: О(n) total, O(1) auxiliary  
  12.   # Stable: Yes  
  13.   #  
  14.   # Algorithms::Sort.bubble_sort [5, 4, 3, 1, 2] => [1, 2, 3, 4, 5]  
  15.   def self.bubble_sort(container)  
  16.     loop do  
  17.       swapped = false  
  18.       (container.size-1).times do |i|  
  19.         if (container[i] <=> container[i+1]) == 1  
  20.           container[i], container[i+1] = container[i+1], container[i] # Swap  
  21.           swapped = true  
  22.         end  
  23.       end  
  24.       break unless swapped  
  25.     end  
  26.     container  
  27.   end  
  28.     
  29.   # Comb sort: A variation on bubble sort that dramatically improves performance.  
  30.   # Source: http://yagni.com/combsort/  
  31.   # Requirements: Needs to be able to compare elements with <=>, and the [] []= methods should  
  32.   # be implemented for the container.  
  33.   # Time Complexity: О(n^2)  
  34.   # Space Complexity: О(n) total, O(1) auxiliary  
  35.   # Stable: Yes  
  36.   #  
  37.   # Algorithms::Sort.comb_sort [5, 4, 3, 1, 2] => [1, 2, 3, 4, 5]  
  38.   def self.comb_sort(container)  
  39.     container  
  40.     gap = container.size  
  41.     loop do  
  42.       gap = gap * 10/13  
  43.       gap = 11 if gap == 9 || gap == 10  
  44.       gap = 1 if gap < 1  
  45.       swapped = false  
  46.       (container.size - gap).times do |i|  
  47.         if (container[i] <=> container[i + gap]) == 1  
  48.           container[i], container[i+gap] = container[i+gap], container[i] # Swap  
  49.           swapped = true  
  50.         end  
  51.       end  
  52.       break if !swapped && gap == 1  
  53.     end  
  54.     container  
  55.   end  
  56.     
  57.   # Selection sort: A naive sort that goes through the container and selects the smallest element,  
  58.   # putting it at the beginning. Repeat until the end is reached.  
  59.   # Requirements: Needs to be able to compare elements with <=>, and the [] []= methods should  
  60.   # be implemented for the container.  
  61.   # Time Complexity: О(n^2)  
  62.   # Space Complexity: О(n) total, O(1) auxiliary  
  63.   # Stable: Yes  
  64.   #  
  65.   # Algorithms::Sort.selection_sort [5, 4, 3, 1, 2] => [1, 2, 3, 4, 5]  
  66.   def self.selection_sort(container)  
  67.     0.upto(container.size-1) do |i|  
  68.       min = i  
  69.       (i+1).upto(container.size-1) do |j|  
  70.         min = j if (container[j] <=> container[min]) == -1  
  71.       end  
  72.       container[i], container[min] = container[min], container[i] # Swap  
  73.     end  
  74.     container  
  75.   end  
  76.     
  77.   # Heap sort: Uses a heap (implemented by the Containers module) to sort the collection.  
  78.   # Requirements: Needs to be able to compare elements with <=>  
  79.   # Time Complexity: О(n^2)  
  80.   # Space Complexity: О(n) total, O(1) auxiliary  
  81.   # Stable: Yes  
  82.   #  
  83.   # Algorithms::Sort.heapsort [5, 4, 3, 1, 2] => [1, 2, 3, 4, 5]  
  84.   def self.heapsort(container)  
  85.     heap = Containers::Heap.new(container)  
  86.     ary = []  
  87.     ary << heap.pop until heap.empty?  
  88.     ary  
  89.   end  
  90.     
  91.   # Insertion sort: Elements are inserted sequentially into the right position.  
  92.   # Requirements: Needs to be able to compare elements with <=>, and the [] []= methods should  
  93.   # be implemented for the container.  
  94.   # Time Complexity: О(n^2)  
  95.   # Space Complexity: О(n) total, O(1) auxiliary  
  96.   # Stable: Yes  
  97.   #  
  98.   # Algorithms::Sort.insertion_sort [5, 4, 3, 1, 2] => [1, 2, 3, 4, 5]  
  99.   def self.insertion_sort(container)  
  100.     return container if container.size < 2  
  101.     (1..container.size-1).each do |i|  
  102.       value = container[i]  
  103.       j = i-1  
  104.       while j >= 0 and container[j] > value do  
  105.         container[j+1] = container[j]  
  106.         j = j-1  
  107.       end  
  108.       container[j+1] = value  
  109.     end  
  110.     container  
  111.   end  
  112.     
  113.   # Shell sort: Similar approach as insertion sort but slightly better.  
  114.   # Requirements: Needs to be able to compare elements with <=>, and the [] []= methods should  
  115.   # be implemented for the container.  
  116.   # Time Complexity: О(n^2)  
  117.   # Space Complexity: О(n) total, O(1) auxiliary  
  118.   # Stable: Yes  
  119.   #  
  120.   # Algorithms::Sort.shell_sort [5, 4, 3, 1, 2] => [1, 2, 3, 4, 5]  
  121.   def self.shell_sort(container)  
  122.     increment = container.size/2  
  123.     while increment > 0 do  
  124.       (increment..container.size-1).each do |i|  
  125.         temp = container[i]  
  126.         j = i  
  127.         while j >= increment && container[j - increment] > temp do  
  128.           container[j] = container[j-increment]  
  129.           j -= increment  
  130.         end  
  131.         container[j] = temp  
  132.       end  
  133.       increment = (increment == 2 ? 1 : (increment / 2.2).round)  
  134.     end  
  135.     container  
  136.   end  
  137.     
  138.   # Quicksort: A divide-and-conquer sort that recursively partitions a container until it is sorted.  
  139.   # Requirements: Container should implement #pop and include the Enumerable module.  
  140.   # Time Complexity: О(n log n) average, O(n^2) worst-case  
  141.   # Space Complexity: О(n) auxiliary  
  142.   # Stable: No  
  143.   #  
  144.   # Algorithms::Sort.quicksort [5, 4, 3, 1, 2] => [1, 2, 3, 4, 5]  
  145.   # def self.quicksort(container)  
  146.   # return [] if container.empty?  
  147.   #  
  148.   # x, *xs = container  
  149.   #  
  150.   # quicksort(xs.select { |i| i < x }) + [x] + quicksort(xs.select { |i| i >= x })  
  151.   # end  
  152.     
  153.   def self.partition(data, left, right)  
  154.     pivot = data[front]  
  155.     left += 1  
  156.    
  157.     while left <= right do  
  158.       if data[frontUnknown] < pivot  
  159.         back += 1  
  160.         data[frontUnknown], data[back] = data[back], data[frontUnknown] # Swap  
  161.       end  
  162.    
  163.       frontUnknown += 1  
  164.     end  
  165.    
  166.     data[front], data[back] = data[back], data[front] # Swap  
  167.     back  
  168.   end  
  169.    
  170.    
  171.   # def self.quicksort(container, left = 0, right = container.size - 1)  
  172.   # if left < right  
  173.   # middle = partition(container, left, right)  
  174.   # quicksort(container, left, middle - 1)  
  175.   # quicksort(container, middle + 1, right)  
  176.   # end  
  177.   # end  
  178.     
  179.   def self.quicksort(container)  
  180.     bottom, top = [], []  
  181.     top[0] = 0  
  182.     bottom[0] = container.size  
  183.     i = 0  
  184.     while i >= 0 do  
  185.       l = top[i]  
  186.       r = bottom[i] - 1;  
  187.       if l < r  
  188.         pivot = container[l]  
  189.         while l < r do  
  190.           r -= 1 while (container[r] >= pivot && l < r)  
  191.           if (l < r)  
  192.             container[l] = container[r]  
  193.             l += 1  
  194.           end  
  195.           l += 1 while (container[l] <= pivot && l < r)  
  196.           if (l < r)  
  197.             container[r] = container[l]  
  198.             r -= 1  
  199.           end  
  200.         end  
  201.         container[l] = pivot  
  202.         top[i+1] = l + 1  
  203.         bottom[i+1] = bottom[i]  
  204.         bottom[i] = l  
  205.         i += 1  
  206.       else  
  207.         i -= 1  
  208.       end  
  209.     end  
  210.     container  
  211.   end  
  212.    
  213.   # Mergesort: A stable divide-and-conquer sort that sorts small chunks of the container and then merges them together.  
  214.   # Returns an array of the sorted elements.  
  215.   # Requirements: Container should implement []  
  216.   # Time Complexity: О(n log n) average and worst-case  
  217.   # Space Complexity: О(n) auxiliary  
  218.   # Stable: Yes  
  219.   #  
  220.   # Algorithms::Sort.mergesort [5, 4, 3, 1, 2] => [1, 2, 3, 4, 5]  
  221.   def self.mergesort(container)  
  222.     return container if container.size <= 1  
  223.     mid = container.size / 2  
  224.     left = container[0...mid]  
  225.     right = container[mid...container.size]  
  226.     merge(mergesort(left), mergesort(right))  
  227.   end  
  228.    
  229.   def self.merge(left, right)  
  230.     sorted = []  
  231.     until left.empty? or right.empty?  
  232.       left.first <= right.first ? sorted << left.shift : sorted << right.shift  
  233.     end  
  234.     sorted + left + right  
  235.   end  
  236.    
  237. end  




Source: http://github.com/kanwei/algorithms/tree/master

posted @ 2011-10-15 19:58  fandyst  阅读(334)  评论(0编辑  收藏  举报