Spaces:
Sleeping
Sleeping
File size: 4,547 Bytes
d916065 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# Natural Language Toolkit: List Sorting
#
# Copyright (C) 2001-2023 NLTK Project
# Author: Steven Bird <[email protected]>
# URL: <https://www.nltk.org/>
# For license information, see LICENSE.TXT
"""
This module provides a variety of list sorting algorithms, to
illustrate the many different algorithms (recipes) for solving a
problem, and how to analyze algorithms experimentally.
"""
# These algorithms are taken from:
# Levitin (2004) The Design and Analysis of Algorithms
##################################################################
# Selection Sort
##################################################################
def selection(a):
"""
Selection Sort: scan the list to find its smallest element, then
swap it with the first element. The remainder of the list is one
element smaller; apply the same method to this list, and so on.
"""
count = 0
for i in range(len(a) - 1):
min = i
for j in range(i + 1, len(a)):
if a[j] < a[min]:
min = j
count += 1
a[min], a[i] = a[i], a[min]
return count
##################################################################
# Bubble Sort
##################################################################
def bubble(a):
"""
Bubble Sort: compare adjacent elements of the list left-to-right,
and swap them if they are out of order. After one pass through
the list swapping adjacent items, the largest item will be in
the rightmost position. The remainder is one element smaller;
apply the same method to this list, and so on.
"""
count = 0
for i in range(len(a) - 1):
for j in range(len(a) - i - 1):
if a[j + 1] < a[j]:
a[j], a[j + 1] = a[j + 1], a[j]
count += 1
return count
##################################################################
# Merge Sort
##################################################################
def _merge_lists(b, c):
count = 0
i = j = 0
a = []
while i < len(b) and j < len(c):
count += 1
if b[i] <= c[j]:
a.append(b[i])
i += 1
else:
a.append(c[j])
j += 1
if i == len(b):
a += c[j:]
else:
a += b[i:]
return a, count
def merge(a):
"""
Merge Sort: split the list in half, and sort each half, then
combine the sorted halves.
"""
count = 0
if len(a) > 1:
midpoint = len(a) // 2
b = a[:midpoint]
c = a[midpoint:]
count_b = merge(b)
count_c = merge(c)
result, count_a = _merge_lists(b, c)
a[:] = result # copy the result back into a.
count = count_a + count_b + count_c
return count
##################################################################
# Quick Sort
##################################################################
def _partition(a, l, r):
p = a[l]
i = l
j = r + 1
count = 0
while True:
while i < r:
i += 1
if a[i] >= p:
break
while j > l:
j -= 1
if j < l or a[j] <= p:
break
a[i], a[j] = a[j], a[i] # swap
count += 1
if i >= j:
break
a[i], a[j] = a[j], a[i] # undo last swap
a[l], a[j] = a[j], a[l]
return j, count
def _quick(a, l, r):
count = 0
if l < r:
s, count = _partition(a, l, r)
count += _quick(a, l, s - 1)
count += _quick(a, s + 1, r)
return count
def quick(a):
return _quick(a, 0, len(a) - 1)
##################################################################
# Demonstration
##################################################################
def demo():
from random import shuffle
for size in (10, 20, 50, 100, 200, 500, 1000):
a = list(range(size))
# various sort methods
shuffle(a)
count_selection = selection(a)
shuffle(a)
count_bubble = bubble(a)
shuffle(a)
count_merge = merge(a)
shuffle(a)
count_quick = quick(a)
print(
("size=%5d: selection=%8d, bubble=%8d, " "merge=%6d, quick=%6d")
% (size, count_selection, count_bubble, count_merge, count_quick)
)
if __name__ == "__main__":
demo()
|