elixr 实现排序算法

冒泡排序:

defmodule BubbleSort do
  @moduledoc """
  Implementation of BubbleSort algorithm (https://en.wikipedia.org/wiki/Bubblesort)
  
  Given an array of numbers, sorts it in ascending order
  using the bubblesort algorithm.
  
  Bubble sort algorithm uses a simple iterative strategy.
  Starting with the first element, it compares it with the second element; if
  the first one is larger, it swaps them, remembers that it performed a swap,
  and continues to compare elements two and three, three and four and so forth.
  When it reaches the end of the array, if at least one swap was performed, it
  starts again at the beginning; if no swap was performed, the array is sorted,
  and the algorithm terminates.
  
  Example (the star denotes the current element):
   [*2, 1, 5, 4, 3]
    1. 2 is larger than 1: swap them
    2. [1, *2, 5, 4, 3]
    3. 2 is smaller than 5: no swap, continue at next element
    4. [1, 2, *5, 4, 3]
    5. 5 is larger than 4: swap them
    6. [1, 2, 4, *5, 3]
    7. 5 is larger than 3: swap them
    8. [1, 2, 4, 3, *5]
    9. end of array is reached; we performed at least one swap, so start again
    10. [*1, 2, 4, 3, 5]
    11. 1 is smaller than 2: no swap, continue at next element
    12. [1, *2, 4, 3, 5]
    13. 2 is smaller than 4: no swap, continue at next element
    14. [1, 2, *4, 3, 5]
    15. 4 is larger than 3: swap them
    14. [1, 2, 3, *4, 5]
    15. 4 is smaller than 5: no swap, continue at next element
    16. [1, 2, 3, 4, *5]
    17. end of array is reached; we performed at least one swap, so start again
    (we'll skip the last couple of steps - the array is sorted, no swaps are performed, and the algorithm terminates)
  
   [2, 1, 5, 4, 3] => [1, 2, 3, 4, 5]
  Complexity: O(n*n)
  """
  require Integer

  @doc """
    take a List and return the List with the numbers ordered
  """
  @spec bubble_pass(list(Integer)) :: list(Integer)
  def bubble_pass([]), do: []

  def bubble_pass([x]), do: [x]

  def bubble_pass([x1 | [x2 | xs]]) do
    case x1 < x2 do
      true -> Enum.concat([x1], bubble_pass(Enum.concat([x2], xs)))
      false -> Enum.concat([x2], bubble_pass(Enum.concat([x1], xs)))
    end
  end

  @spec bubble_sort(list(Integer)) :: list(Integer)
  def bubble_sort(lst) do
    bpassed = bubble_pass(lst)

    case bpassed == lst do
      true -> bpassed
      false -> bubble_sort(bpassed)
    end
  end
end

 

快速排序

defmodule QuickSort do
  @moduledoc """
  Implementation of QuickSort algorithm (https://en.wikipedia.org/wiki/Quicksort)
  
  You will be given an array of numbers, you have to sort numbers in ascending order
  using quick sort algorithm.
  
  Quick sort algorithm uses a divide and conquer strategy.
  It takes a pivot, and sort other numbers in functions of the pivot, divided them
  in a smaller and a bigger group. Execute this step until there is empty list.
  
  Example:
   [2, 1, 5, 4, 3]
    1. pivot:2 smaller:[1] bigger:[5, 4, 3]
    2. 2 [1] [5, 4, 3]
    3. 2 [1] |
             | 5 [4, 3] []
    4. 2 [1] |
               | 5 |
                   | 4 [3] []
    5. [1, 2, 3, 4, 5] # Recursion reunite all splited lists.
  
   [2, 1, 5, 4, 3] => [1, 2, 3, 4, 5]
  Complexity: O(n log n)
  """
  require Integer

  @doc """
    take a List and return the List with the numbers ordered
  """
  @spec quick_sort(list(Integer)) :: list(Integer)
  def quick_sort([]), do: []

  def quick_sort([head | tail]) do
    smaller = Enum.filter(tail, fn x -> x <= head end) |> quick_sort()
    bigger = Enum.filter(tail, fn x -> x > head end) |> quick_sort()

    Enum.concat(smaller, [head]) |> Enum.concat(bigger)
  end


end

  

 

归并排序:

defmodule MergeSort do
  @moduledoc """
  Implementation of MergeSort algorithm (https://en.wikipedia.org/wiki/Merge_sort)
  
  You will be given an array of numbers, you have to sort numbers in ascending order
  using merge sort algorithm.
  
  Merge sort algorithm uses a divide and conquer strategy.
  It divide a list in two half. We compare the two heads of the halfs.
  If the left one is smaller, we recursively sort with merge on tail of
  left and the all right, and we put the head left at the top.
  Else we do the same on reversed.
  
  Example:
    1. [2, 1, 5, 4, 3]
    2. [2, 1, 5] [4, 3]
    3. [2] [1, 5] | [3] [4]
    4. [1, 2, 5] | [3] [4]
    5. [1, 2, 3, 4, 5]  # Recursite reunite all the small lists
  
   [2, 1, 5, 4, 3] => [1, 2, 3, 4, 5]
  
  Complexity: O(n log n)
  """
  require Integer

  @doc """
    take a List and return the List with the numbers ordered
  """
  @spec merge_sort(list(Integer)) :: list(Integer)
  def merge_sort([]), do: []
  def merge_sort([x]), do: [x]

  def merge_sort(numbers) do
    l = length(numbers)
    half = div(l, 2)
    right = merge_sort(Enum.take(numbers, half))
    left = merge_sort(Enum.drop(numbers, half))
    merge(right, left)
  end

  @spec merge(list(Integer), list(Integer)) :: list(Integer)
  defp merge(left, []), do: Enum.concat([left])
  defp merge([], right), do: Enum.concat([right])

  defp merge([h_left | t_left], [h_right | t_right]) do
    case h_left < h_right do
      true -> merge(t_left, [h_right] ++ t_right) |> concat(h_left)
      false -> Enum.concat([h_left], t_left) |> merge(t_right) |> concat(h_right)
    end
  end

  @spec concat(list(Integer), Integer) :: list(Integer)
  defp concat(list, element), do: Enum.concat([element], list)
end

 

选择排序:

defmodule SelectionSort do
  @moduledoc """
  Implementation of SelectionSort algorithm (https://en.wikipedia.org/wiki/Selection_sort)
  
  You will be given an array of numbers, you have to sort numbers in ascending order
  using selection sort algorithm.
  
  The algorithm divides the input list into two parts:
    - A sorted sublist of items which is built up from left to right at the front (left) of the list
    - A sublist of the remaining unsorted items that occupy the rest of the list
  Initially, the sorted sublist is empty and the unsorted sublist is the entire input list.
  The algorithm proceeds by finding the smallest (or largest, depending on sorting order)
  element in the unsorted sublist, exchanging (swapping) it with the leftmost unsorted
  element (putting it in sorted order), and moving the sublist boundaries one element to the right.
  
  Example:
    Input: [11, 25, 12, 22, 64]
  
    | Sorted sublist         | Unsorted sublist         | Least element in unsorted list
    | []                     | [11, 25, 12, 22, 64]     | 11
    | [11]                   | [25, 12, 22, 64]         | 12
    | [11, 12]               | [25, 22, 64]             | 22
    | [11, 12, 22]           | [25, 64]                 | 25
    | [11, 12, 22, 25]       | [64]                     | 64
    | [11, 12, 22, 25, 64]| []                    |
  
   Complexity: O(n^2)
  """
  require Integer

  @doc """
    take a List and return the List with the numbers ordered
  """
  @spec selection_sort(list(Integer)) :: list(Integer)
  def selection_sort(list) do
    do_selection(list, [])
  end

  def do_selection([head | []], acc) do
    acc ++ [head]
  end

  def do_selection(list, acc) do
    min = min(list)
    do_selection(:lists.delete(min, list), acc ++ [min])
  end

  defp min([first | [second | []]]) do
    smaller(first, second)
  end

  defp min([first | [second | tail]]) do
    min([smaller(first, second) | tail])
  end

  defp smaller(e1, e2) do
    if e1 <= e2 do
      e1
    else
      e2
    end
  end
end

 

 

 

使用Erlang实现简单的排序算法:快速排序,冒泡排序,插入排序 - 孤独信徒 - 博客园 (cnblogs.com)

posted @ 2022-06-24 17:01  孤独信徒  阅读(31)  评论(0编辑  收藏  举报