# 用Python实现常见排序算法

2015.08.20 11:17 8947浏览

``````def insertion_sort(sort_list):
iter_len = len(sort_list)
if iter_len < 2:
return sort_list
for i in range(1, iter_len):
key = sort_list[i]
j = i - 1
while j >= 0 and sort_list[j] > key:
sort_list[j+1] = sort_list[j]
j -= 1
sort_list[j+1] = key
return sort_list``````

``````def bubble_sort(sort_list):
iter_len = len(sort_list)
if iter_len < 2:
return sort_list
for i in range(iter_len-1):
for j in range(iter_len-i-1):
if sort_list[j] > sort_list[j+1]:
sort_list[j], sort_list[j+1] = sort_list[j+1], sort_list[j]
return sort_list``````

``````def selection_sort(sort_list):
iter_len = len(sort_list)
if iter_len < 2:
return sort_list
for i in range(iter_len-1):
smallest = sort_list[i]
location = i
for j in range(i, iter_len):
if sort_list[j] < smallest:
smallest = sort_list[j]
location = j
if i != location:
sort_list[i], sort_list[location] = sort_list[location], sort_list[i]
return sort_list``````

``sort_list[i], sort_list[location] = sort_list[location], sort_list[i]``

``````class merge_sort(object):
def _merge(self, alist, p, q, r):
left = alist[p:q+1]
right = alist[q+1:r+1]
for i in range(p, r+1):
if len(left) > 0 and len(right) > 0:
if left[0] <= right[0]:
alist[i] = left.pop(0)
else:
alist[i] = right.pop(0)
elif len(right) == 0:
alist[i] = left.pop(0)
elif len(left) == 0:
alist[i] = right.pop(0)

def _merge_sort(self, alist, p, r):
if p<r:
q = int((p+r)/2)
self._merge_sort(alist, p, q)
self._merge_sort(alist, q+1, r)
self._merge(alist, p, q, r)

def __call__(self, sort_list):
self._merge_sort(sort_list, 0, len(sort_list)-1)
return sort_list``````

``````class heap_sort(object):
def _left(self, i):
return 2*i+1
def _right(self, i):
return 2*i+2
def _parent(self, i):
if i%2==1:
return int(i/2)
else:
return i/2-1

def _max_heapify(self, alist, i, heap_size=None):
length = len(alist)

if heap_size is None:
heap_size = length

l = self._left(i)
r = self._right(i)

if l < heap_size and alist[l] > alist[i]:
largest = l
else:
largest = i
if r < heap_size and alist[r] > alist[largest]:
largest = r

if largest!=i:
alist[i], alist[largest] = alist[largest], alist[i]
self._max_heapify(alist, largest, heap_size)

def _build_max_heap(self, alist):
roop_end = int(len(alist)/2)
for i in range(0, roop_end)[::-1]:
self._max_heapify(alist, i)

def __call__(self, sort_list):
self._build_max_heap(sort_list)
heap_size = len(sort_list)
for i in range(1, len(sort_list))[::-1]:
sort_list[0], sort_list[i] = sort_list[i], sort_list[0]
heap_size -= 1
self._max_heapify(sort_list, 0, heap_size)

return sort_list``````

``````class quick_sort(object):
def _partition(self, alist, p, r):
i = p-1
x = alist[r]
for j in range(p, r):
if alist[j] <= x:
i += 1
alist[i], alist[j] = alist[j], alist[i]
alist[i+1], alist[r] = alist[r], alist[i+1]
return i+1

def _quicksort(self, alist, p, r):
if p < r:
q = self._partition(alist, p, r)
self._quicksort(alist, p, q-1)
self._quicksort(alist, q+1, r)

def __call__(self, sort_list):
self._quicksort(sort_list, 0, len(sort_list)-1)
return sort_list``````

``````import sys
sys.setrecursionlimit(99999)``````

2）第二种方法就是采用另外一个版本的分区函数，称为随机化分区函数。由于之前我们的选择都是子序列的最后一个数，因此对于特殊情况的健壮性就差了许多。现在我们随机从子序列选择基准元素，这样可以减少对特殊情况的差错率。新的randomize partition函数如下：

``````def _randomized_partition(self, alist, p, r):
i = random.randint(p, r)
alist[i], alist[r] = alist[r], alist[i]
return self._partition(alist, p, r)``````

``````import random
class randomized_quick_sort(quick_sort):
def _randomized_partition(self, alist, p, r):
i = random.randint(p, r)
alist[i], alist[r] = alist[r], alist[i]
return self._partition(alist, p, r)

def _quicksort(self, alist, p, r):
if p<r:
q = self._randomized_partition(alist, p, r)
self._quicksort(alist, p, q-1)
self._quicksort(alist, q+1, r)``````

``````def quick_sort_2(sort_list):
if len(sort_list)<=1:
return sort_list
return quick_sort_2([lt for lt in sort_list[1:] if lt<sort_list[0]]) + \
sort_list[0:1] + \
quick_sort_2([ge for ge in sort_list[1:] if ge>=sort_list[0]])``````

``````class counting_sort(object):
def _counting_sort(self, alist, k):
alist3 = [0 for i in range(k)]
alist2 = [0 for i in range(len(alist))]
for j in alist:
alist3[j] += 1
for i in range(1, k):
alist3[i] = alist3[i-1] + alist3[i]
for l in alist[::-1]:
alist2[alist3[l]-1] = l
alist3[l] -= 1
return alist2

def __call__(self, sort_list, k=None):
if k is None:
import heapq
k = heapq.nlargest(1, sort_list)[0] + 1
return self._counting_sort(sort_list, k)``````

1. 当需要排序的时候，尽量设法使用内建Python列表的sort方法。
2. 当需要搜索的时候，尽量设法使用内建的字典。

``````def normal_find_same(alist):
length = len(alist)
for i in range(length):
for j in range(i+1, length):
if alist[i] == alist[j]:
return True
return False``````

``````import time
import random

def record_time(func, alist):
start = time.time()
func(alist)
end = time.time()

return end - start

def quick_find_same(alist):
alist.sort()
length = len(alist)
for i in range(length-1):
if alist[i] == alist[i+1]:
return True
return False

if __name__ == "__main__":
methods = (normal_find_same, quick_find_same)
alist = range(5000)
random.shuffle(alist)

for m in methods:
print 'The method %s spends %s' % (m.__name__, record_time(m, alist))``````

1.6个最佳的开源Python应用服务器

2.Python初学者的17个技巧

3.Python正则表达式指南

18人点赞

Web前端工程师

2503

8.4万

### 风间影月说签约讲师

51篇手记，涉及Java、MySQL、Redis、Spring等方向

### Tony Bai 说签约讲师

151篇手记，涉及Go、C、Java、Python等方向

• 18
• 评论
• 收藏
• 共同学习，写下你的评论

0/150