插入排序
def insertion_sort(list2):
for i in range(1, len(list2)):
save = list2[i]
j = i
while j > 0 and list2[j - 1] > save:
list2[j] = list2[j - 1]
j -= 1
list2[j] = save
def insert_sort(lst):
for i in range(1, len(lst)):
x = lst[i]
for j in range(i, -1, -1):
if lst[j-1].key > x.key:
lst[j] = lst[j-1]
else: break
lst[j] = x
选择排序
def select_sort(lst):
for i in range(len(lst)-1):
k = i
for j in range(i, len(lst)):
if lst[j].key < lst[k].key:
k = j
if i != k:
lst[i], lst[k] = lst[k], lst[i]
起泡
def bubble_sort(lst):
for i in range(len(lst)):
for j in range(1,len(lst)-i):
if lst[j-1].key > lst[j].key:
lst[j-1], lst[j] = lst[j], lst[j-1]
快排
def quick_sort(lst):
qsort_rec(lst, 0, len(lst)-1)
def qsort_rec(lst, l, r):
if l >= r: return # 无记录或一个记录
i = l; j = r; pivot = lst[i] # lst[i]为初始空位
while i < j: # 找 pivot 的最终位置
... ... # 用 j 向左扫描找小于 pivot 的记录并移到左边
... ... # 用 i 向右扫描找大于 pivot 的记录并移到右边
lst[i] = pivot # 将 pivot 存入其最终位置
qsort_rec(lst, l, i-1) # 递归处理左半区间
qsort_rec(lst, i+1, r) # 递归处理右半区间
def qsort_rec(lst, l, r):
if l >= r: return 无记录或一个记录
i = l; j = r
pivot = lst[i] # lst[i] 是初始空位
while i < j: # 找pivot 的最终位置
while i < j and lst[j].key >= pivot.key:
j -= 1 # 用j 向左扫描找小于pivot 的记录
if i < j:
lst[i] = lst[j]; i += 1 #小记录移到左边
while i < j and lst[i].key <= pivot.key:
i += 1 # 用i 向右扫描找大于pivot 的记录
if i < j:
lst[j] = lst[i]; j -= 1 # 大记录移到右边
lst[i] = pivot # 将pivot 存入其最终位置
qsort_rec(lst, l, i-1) # 递归处理左半区间
qsort_rec(lst, i+1, r) # 递归处理右半区间
归并
def merge(left, right):
i, j = 0, 0
result = []
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result += left[i:]
result += right[j:]
return result
def merge_sort(lists):
# 归并排序
if len(lists) <= 1:
return lists
num = len(lists) // 2
left = merge_sort(lists[:num])
right = merge_sort(lists[num:])
return merge(left, right)
堆排序
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 xrange(HeapSize//2,-1,-1):#从后往前出数
MAX_Heapify(heap,HeapSize,i)
def HeapSort(heap):#将根节点取出与最后一位做对调,对前面len-1个节点继续进行对调整过程。
Build_MAX_Heap(heap)
for i in range(len(heap)-1,-1,-1):
heap[0],heap[i] = heap[i],heap[0]
MAX_Heapify(heap, i, 0)
return heap
1.使用数组表示完全二叉树的方法,如何访问父节点,访问子节点,如何判断叶子
2. 理解sift-up和sift-down两个操作,其实就是不断的向上或者向下比较并交换,直到根节点或者叶子节点。
3. 建堆其实只需要n/2次sift-down或者sift-up操作即可
4. 排序其实就是把堆顶元素移到最终位置,并把堆大小减1,然后sift-up或者sift-down就可以了。
耐着点性子去理解算法,其实建堆和堆的调整的相关操作是贪心算法的重要的一个工具,如果不懂堆,如何写出贪心类算法?贪心是各种算法题目的一个基础类型,比如霍夫曼编码其实就是贪心算法,肯定是要会写的。试着从算法设计思想的角度去理解算法,才能吃透。