排序算法小结
2018-03-20 16:48 zxbob 阅读(190) 评论(0) 收藏 举报排序算法一直以来是我的心病,这次为了搞定这块内容,进行了一次系统的学习,结合大神的讲解以及个人的总结,梳理了以下的解决方案,顺便给出相关的迁移问题以及解决方案。
概况:
排序一般分为选择排序和插入排序这两大类,其余排序都是在这两块上的优化和深入。
这里不得不提到时间复杂度,虽然为O(n*2),可是在特定的场合下,插入排序还是比较快的,尤其是在近乎有序的情况下,一般在数据量比较小而接近的
情况下使用比较好。
插入排序衍生出冒泡排序和希尔排序
高级排序(O(nlogn)):
归并排序、快速排序、双路/三路快速排序、堆排序
下面给出相关的代码实例(python格式):
选择排序:
def selectSort(arr): """ 选择排序 """ for i in range(0,len(arr)): # 在[i,n)中选择最小的索引 min_index = i for j in range(i+1,len(arr)): if arr[j] < arr[min_index]: min_index = j # 交换i与min_index的位置 # swap(arr[i], arr[min_index]) python中不需要使用这个,内存空间中局部变量无效 arr[i], arr[min_index] = arr[min_index], arr[i]
插入排序:
def insertSort(arr):
"""
插入排序
"""
for i in range(1, len(arr)):
# 选择arr[i]的位置
a = arr[i]
j = i
for j in range(1, i+1)[::-1]:
# if arr[j-1] > arr[j]:
# arr[j-1], arr[j] = arr[j], arr[j-1]
if arr[j-1] > a:
arr[j] = arr[j-1]
else:
break
arr[j] = a
快速排序:
def _parition(arr, s, e):
"""
找拆分位置
arr[s...index -1]<arr[index] arr[index+1....e]> arr[index]
"""
#初始第一个
base = arr[s]
j = s
#使得 arr[i+1....j-1]< base and arr[j+1....e]>base
for i in range(s+1, e+1):
if arr[i] < base:
arr[j+1], arr[i] = arr[i], arr[j+1]
j += 1
arr[s], arr[j] = arr[j], arr[s]
return j
def _quickSort(arr, l, r, n):
"""
进行快排
"""
if r < l:
return
index = _parition(arr, l, r)
if index == n:
return index
_quickSort(arr, l, index-1, n)
_quickSort(arr, index+1, r, n)
def quickSort(arr, n):
"""
快速排序
"""
return _quickSort(arr, 0, len(arr)-1, n)
归并排序:
def __merge_sort(arr, s, mid, e):
"""
归并arr[s...mid] arr[mid+1....e]
"""
#初始化归并空间
merge_arr = [0] * (e-s+1)
#赋值
for i in range(s, e+1):
merge_arr[i-s] = arr[i]
i = s
j = mid+1
#归并
for k in range(s, e+1):
if i > mid:
arr[k] = merge_arr[j-s]
j += 1
elif j > e:
arr[k] = merge_arr[i-s]
i += 1
elif merge_arr[i-s] <merge_arr[j-s]:
arr[k] = merge_arr[i-s]
i += 1
else:
arr[k] = merge_arr[j-s]
j += 1
def _mergeSort(arr, s, e):
if s >= e:
return
#改进数据量小的时候,用插入排序
if e-s <20:
insertSort(arr)
return
#中间位置
mid = s + (e-s)//2
_mergeSort(arr, s, mid)
_mergeSort(arr, mid+1, e)
if arr[mid] < arr[mid+1]:
__merge_sort(arr, s, mid, e)
def mergeSort(arr):
"""
归并排序
"""
_mergeSort(arr, 0, len(arr)-1)
堆排序:
def MAX_Heapify(heap, HeapSize, root):
left = 2*root + 1
right = left + 1
larger = root
if left < HeapSize and heap[larger] < heap[left]:
larger = left
if right < HeapSize and heap[larger] < heap[right]:
larger = right
if larger != root:#如果做了堆调整则larger的值等于左节点或者右节点的,这个时候做对调值操作
heap[larger],heap[root] = heap[root],heap[larger]
MAX_Heapify(heap, HeapSize, larger)
def Build_MAX_Heap(heap):
HeapSize = len(heap)#将堆的长度当独拿出来方便
for i in range((HeapSize -2)//2,-1,-1):#从后往前出数
MAX_Heapify(heap,HeapSize,i)
def heapSort(arr):
Build_MAX_Heap(arr)
for i in range(len(arr)-1,-1,-1):
arr[0],arr[i] = arr[i],arr[0]
MAX_Heapify(arr, i, 0)
return arr
以下是随机生成测试数据和计算排序时长的方式:
def generArr(l, r, n):
arr = [0] * n
for i in range(0, n):
arr[i] = random.randint(l,n)
return arr
def countTime(arr, func = None):
"""
计算时长
"""
start = time.time()
func(arr)
end = time.time()
print(func.__name__, '时长{}s'.format(round((end-start), 5)))
计算结果如下:
def main():
"""
主函数
"""
arr = generArr(0, 100, 10000)
arrs = generArr(0, 100, 10000)
countTime(arr, mergeSort)
countTime(arrs, insertSort)
if __name__ == '__main__':
main()
D:\anacond\python.exe E:/cources_python/data_structure/algorithm/sort_demo.py
mergeSort 时长15.77121s
insertSort 时长7.39828s
Process finished with exit code 0
浙公网安备 33010602011771号