常见的排序算法
冒泡排序
每次比较相邻两个数的大小,如果不是预期排序就交换顺序。
import random
def bubble_sort(blist):
list_len = len(blist)
for i in range(list_len):
for j in range(list_len - 1):
if blist[j] > blist[j+1]:
blist[j], blist[j+1] = blist[j+1], blist[j]
if __name__ == '__main__':
ls = [random.randint(0, 1000) for i in range(50)]
print(ls)
bubble_sort(ls)
print(ls)
排序结果
#数据随机生成
[100, 876, 270, 434, 616, 175, 334, 791, 22, 626, 955, 907, 538, 726, 515, 455, 996, 1000, 294, 795, 356, 722, 797, 719, 87, 299, 990, 953, 823, 534, 790, 585, 764, 306, 391, 248, 75, 142, 218, 120, 867, 151, 885, 437, 871, 927, 637, 346, 93, 476]
[22, 75, 87, 93, 100, 120, 142, 151, 175, 218, 248, 270, 294, 299, 306, 334, 346, 356, 391, 434, 437, 455, 476, 515, 534, 538, 585, 616, 626, 637, 719, 722, 726, 764, 790, 791, 795, 797, 823, 867, 871, 876, 885, 907, 927, 953, 955, 990, 996, 1000]
选择排序
第一轮的时候,所有的元素都和第一个元素进行比较,如果比第一个元素小,就和第一个元素进行交换,在这轮比较完后,就找到了最小的元素;第二轮的时候所有的元素都和第二个元素进行比较找出第二个位置的元素,以此类推。
import random
def select_sort(slist):
list_len = len(slist)
for i in range(list_len):
for j in range(i + 1, list_len):
if slist[i] > slist[j]:
slist[i], slist[j] = slist[j], slist[i]
if __name__ == '__main__':
ls = [random.randint(0, 1000) for i in range(50)]
print(ls)
select_sort(ls)
print(ls)
排序结果
#数据随机生成
[612, 148, 571, 433, 724, 396, 720, 703, 853, 486, 991, 856, 800, 723, 911, 848, 873, 611, 845, 268, 821, 847, 149, 372, 686, 801, 762, 720, 279, 272, 820, 895, 629, 195, 777, 908, 625, 803, 503, 13, 197, 422, 961, 814, 327, 598, 831, 957, 682, 295]
[13, 148, 149, 195, 197, 268, 272, 279, 295, 327, 372, 396, 422, 433, 486, 503, 571, 598, 611, 612, 625, 629, 682, 686, 703, 720, 720, 723, 724, 762, 777, 800, 801, 803, 814, 820, 821, 831, 845, 847, 848, 853, 856, 873, 895, 908, 911, 957, 961, 991]
插入排序
将序列分为已排序序列和未排序序列,每次从未排序序列中取出一个数,插入到已排序的序列中。
import random
def insert_sort(ilist):
list_len = len(ilist)
for i in range(1, list_len):
num = ilist.pop(i)
for j in range(i-1, -1, -1):
if num > ilist[j]:
ilist.insert(j+1, num)
break
if j == 0:
ilist.insert(0, num)
if __name__ == '__main__':
ls = [random.randint(0, 1000) for i in range(50)]
print(ls)
insert_sort(ls)
print(ls)
排序结果
#数据随机生成
[897, 349, 40, 577, 678, 70, 809, 779, 16, 779, 371, 261, 618, 319, 895, 455, 521, 664, 469, 380, 149, 735, 422, 604, 639, 24, 112, 997, 5, 643, 12, 854, 315,
207, 225, 553, 290, 527, 524, 797, 880, 979, 810, 35, 341, 328, 617, 410, 869, 351]
[5, 12, 16, 24, 35, 40, 70, 112, 149, 207, 225, 261, 290, 315, 319, 328, 341, 349, 351, 371, 380, 410, 422, 455, 469, 521, 524, 527, 553, 577, 604, 617, 618, 639, 643, 664, 678, 735, 779, 779, 797, 809, 810, 854, 869, 880, 895, 897, 979, 997]
希尔排序
将数组列在一个表中并对列分别进行插入排序,重复这过程,
每次用更长的列(步长更长了,列数更少了)来进行。最后整个表就只有一列了。
import random
def shell_sort(slist):
list_len = len(slist)
gap = list_len // 2
while gap:
for i in range(gap, list_len):
tmp = i
for j in range(i, -1, -gap):
if slist[tmp] < slist[j]:
slist[tmp], slist[j] = slist[j], slist[tmp]
tmp = j
gap = gap // 2
if __name__ == '__main__':
ls = [random.randint(0, 1000) for i in range(50)]
print(ls)
shell_sort(ls)
print(ls)
排序结果
#数据随机生成
[54, 410, 371, 988, 276, 194, 101, 446, 497, 224, 616, 495, 652, 146, 539, 367, 515, 278, 201, 142, 793, 718, 700, 803, 523, 873, 288, 612, 712, 283, 24, 327,
446, 609, 934, 283, 367, 502, 792, 877, 726, 68, 150, 406, 406, 921, 499, 778, 24, 977]
[24, 24, 54, 68, 101, 142, 146, 150, 194, 201, 224, 276, 278, 283, 283, 288, 327, 367, 367, 371, 406, 406, 410, 446, 446, 495, 497, 499, 502, 515, 523, 539, 609, 612, 616, 652, 700, 712, 718, 726, 778, 792, 793, 803, 873, 877, 921, 934, 977, 988]
归并排序
归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。
将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,取较小的数,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。
import random
def merge_sort(mlist):
def merge_divide(mlist, left, right):
if left >= right:
return
mid = (left+right)//2
merge_divide(mlist, left, mid)
merge_divide(mlist, mid+1, right)
merge_conquer(mlist, left, mid, right)
def merge_conquer(mlist, left, mid, right):
res = []
left_pos = left
right_pos = mid+1
while left_pos <= mid and right_pos <= right:
if mlist[left_pos] <= mlist[right_pos]:
res.append(mlist[left_pos])
left_pos += 1
else:
res.append(mlist[right_pos])
right_pos += 1
while left_pos <= mid:
res.append(mlist[left_pos])
left_pos += 1
while right_pos <= right:
res.append(mlist[right_pos])
right_pos += 1
for i in range(left, right+1):
mlist[i] = res[i-left]
merge_divide(mlist, 0, len(mlist)-1)
if __name__ == '__main__':
ls = [random.randint(0, 1000) for i in range(50)]
print(ls)
merge_sort(ls)
print(ls)
排序结果
#数据随机生成
[457, 830, 429, 160, 932, 584, 394, 740, 834, 674, 201, 224, 475, 184, 326, 849, 607, 29, 805, 953, 530, 657, 224, 918, 485, 646, 1000, 623, 404, 733, 478, 386, 999, 856, 500, 647, 65, 39, 389, 60, 292, 812, 564, 502, 728, 486, 907, 934, 97, 324]
[29, 39, 60, 65, 97, 160, 184, 201, 224, 224, 292, 324, 326, 386, 389, 394, 404, 429, 457, 475, 478, 485, 486, 500, 502, 530, 564, 584, 607, 623, 646, 647, 657, 674, 728, 733, 740, 805, 812, 830, 834, 849, 856, 907, 918, 932, 934, 953, 999, 1000]
快速排序
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
import random
def quick_sort(qlist):
if qlist == []:
return []
else :
q = qlist[0]
bigger_list = quick_sort([num for num in qlist[1:] if num >= q])
less_list = quick_sort([num for num in qlist[1:] if num < q])
return less_list + [q] + bigger_list
if __name__ == '__main__':
ls = [random.randint(0, 1000) for i in range(50)]
print(ls)
ls = quick_sort(ls)
print(ls)
排序结果
#数据随机生成
[86, 710, 253, 892, 951, 430, 325, 621, 95, 290, 89, 952, 734, 711, 280, 84, 834, 467, 862, 731, 744, 388, 577, 427, 89, 500, 803, 279, 461, 669, 951, 602, 936, 984, 873, 440, 880, 897, 172, 722, 887, 61, 324, 263, 369, 979, 647, 453, 54, 626]
[54, 61, 84, 86, 89, 89, 95, 172, 253, 263, 279, 280, 290, 324, 325, 369, 388, 427, 430, 440, 453, 461, 467, 500, 577, 602, 621, 626, 647, 669, 710, 711, 722,
731, 734, 744, 803, 834, 862, 873, 880, 887, 892, 897, 936, 951, 951, 952, 979, 984]
计数排序
计数排序用待排序的数值作为计数数组(列表)的下标,统计每个数值的个数,然后依次输出即可。
import random
def count_sort(clist):
clist_len = len(clist)
cnt = [0]*(max(clist)+1)
tmp = []*clist_len
for i in range(clist_len):
cnt[clist[i]] += 1
for i in range(len(cnt)):
for _ in range(cnt[i]):
tmp.append(i)
return tmp
if __name__ == '__main__':
ls = [random.randint(0, 1000) for i in range(50)]
print(ls)
ls = count_sort(ls)
print(ls)
排序结果
#数据随机生成
[490, 67, 157, 316, 869, 497, 172, 761, 107, 20, 968, 371, 690, 431, 82, 886, 84, 267, 496, 913, 681, 451, 846, 245, 641, 700, 338, 164, 925, 938, 348, 760, 277, 639, 753, 338, 700, 100, 192, 626, 809, 400, 248, 648, 673, 845, 430, 748, 315, 339]
[20, 67, 82, 84, 100, 107, 157, 164, 172, 192, 245, 248, 267, 277, 315, 316, 338, 338, 339, 348, 371, 400, 430, 431, 451, 490, 496, 497, 626, 639, 641, 648, 673, 681, 690, 700, 700, 748, 753, 760, 761, 809, 845, 846, 869, 886, 913, 925, 938, 968]
基数排序
每个数从低位往高位取,每次取一位数,并对所有数的同一位计数排序。
import math
import random
def radix_sort(mlist):
def get_bit(num, index):
return num//(int(math.pow(10, index)))%10
max_num = max(mlist)
max_bit = int(math.log10(max_num))+1
for i in range(0, max_bit):
res = []
radix = [[] for _ in range(10)]
for num in mlist:
radix[get_bit(num, i)].append(num)
for j in range(10):
res += radix[j]
mlist = res
return mlist
if __name__ == '__main__':
ls = [random.randint(0, 1000) for i in range(50)]
print(ls)
ls = radix_sort(ls)
print(ls)
排序结果
#数据随机生成
[873, 153, 619, 43, 706, 847, 751, 860, 363, 234, 561, 440, 591, 726, 523, 446, 769, 38, 674, 261, 691, 827, 455, 453, 332, 350, 53, 868, 370, 788, 834, 900, 804, 99, 568, 223, 127, 191, 618, 264, 99, 693, 363, 691, 268, 844, 300, 356, 808, 642]
[38, 43, 53, 99, 99, 127, 153, 191, 223, 234, 261, 264, 268, 300, 332, 350, 356, 363, 363, 370, 440, 446, 453, 455, 523, 561, 568, 591, 618, 619, 642, 674, 691, 691, 693, 706, 726, 751, 769, 788, 804, 808, 827, 834, 844, 847, 860, 868, 873, 900]