2、树、二叉树、堆排序、归并排序、希尔排序、小结
1、树与二叉树
(1)二叉树
(2)二叉树的存储方式
(3)二叉树小结
2、堆
(1)什么是堆
(2)调整
3、堆排序的过程
(1)构造堆
市长 镇长 村长 ***民
(2)挨个出数
(3)堆排序代码
# -*- coding: utf-8 -*- # @Time : 2018/07/31 0031 9:57 # @Author : Venicid def sift(data, low, high): """ 调整 :param data: 列表 :param low: 堆根节点的位置 :param high: 堆最后一个节点的位置 :return: """ i = low # 父亲的位置 j = 2 * i + 1 # 孩子的位置 tmp = data[i] # 原省长退休 while j <= high: # 孩子在堆里 if j + 1 <= high and data[j] < data[j + 1]: # if右孩子存在且右孩子更大 # if j + 1 <= high and data[j] > data[j + 1]: # if右孩子存在且右孩子更大 j += 1 if data[j] > tmp: # 孩子比最高领导大 # if data[j] < tmp: # 孩子比最高领导大 data[i] = data[j] # 孩子上移一层 i = j # 孩子成为新父亲 j = 2 * i + 1 # 新孩子 else: break data[i] = tmp # 省长放到对应的位置上(村民/叶子节点) def heap_sort(data): n = len(data) # 1.建堆 for i in range(n // 2, -1, -1): sift(data, i, n - 1) # 堆建好了 # 2.挨个出数 for j in range(n - 1, -1, -1): # j表示堆的最后 data[0], data[j] = data[j], data[0] # 领导退休,***民上位 sift(data, 0, j - 1) # 调整出新领导 import random data = list(range(10)) random.shuffle(data) print(data) heap_sort(data) print(data)
建堆
(4)练习
4、一次归并排序:两段有序
(1)流程图
(2)一次归并排序代码
# -*- coding: utf-8 -*- # @Time : 2018/07/31 0031 10:17 # @Author : Venicid def merge(li, low, mid, high): i = low j = mid + 1 ltmp = [] # 排序前,新建一个list,存放数据 # 1.两段有序,分别比较大小,append while i <= mid and j <= high: if li[i] < li[j]: ltmp.append(li[i]) i += 1 else: ltmp.append(li[j]) j += 1 # 2.一边没有数据,另一边全部append到ltmp while i <= mid: ltmp.append(li[i]) i += 1 while j <= high: ltmp.append(li[j]) j += 1 # 3.ltmp的值给li li[low:high + 1] = ltmp li = [1,3,4,56,2,3,5,7,90,122] low = 0 high = len(li)-1 mid = (low+high) //2 +1 merge(li,low,mid,high) print(li)
5、归并排序+递归
(1)有了归并怎么用?
(2)递归+合并代码
# -*- coding: utf-8 -*- # @Time : 2018/07/31 0031 10:17 # @Author : Venicid def merge(li, low, mid, high): i = low j = mid + 1 ltmp = [] # 排序前,新建一个list,存放数据 # 1.两段有序,分别比较大小,append while i <= mid and j <= high: if li[i] < li[j]: ltmp.append(li[i]) i += 1 else: ltmp.append(li[j]) j += 1 # 2.一边没有数据,另一边全部append到ltmp while i <= mid: ltmp.append(li[i]) i += 1 while j <= high: ltmp.append(li[j]) j += 1 # 3.ltmp的值给li li[low:high + 1] = ltmp def mergesort(li, low, high): if low < high: # 分解 mid = (low+high) // 2 mergesort(li, low, mid) mergesort(li, mid+1, high) # 合并 merge(li, low, mid, high) import random data = list(range(100)) random.shuffle(data) print(data) mergesort(data,0, len(data)-1) print(data)
6、快速排序、堆排序、归并排序-小结
7、希尔排序
(1)排序思路
# -*- coding: utf-8 -*- # @Time : 2018/07/31 0031 10:50 # @Author : Venicid def insert_sort(li): """插入排序""" for i in range(1, len(li)): # 从第二个位置,即下标为1的元素开始向前插入 tmp = li[i] # 摸到的牌 j = i - 1 # j 指向有序区最后位置 while j >= 0 and li[j] > tmp: li[j + 1] = li[j] j = j - 1 li[j + 1] = tmp # 希尔排序 与插入排序区别就是把1变成d def shell_sort(li): gap = len(li) // 2 print(gap,len(li)) while gap >= 1: for i in range(gap, len(li)): tmp = li[i] j = i - gap while j >= 0 and li[j] > tmp: li[j + gap] = li[j] j = j - gap li[j + gap] = tmp gap //=2 import random data = list(range(10)) random.shuffle(data) print(data) shell_sort(data) print(data)
8、排序小结
稳定性
2 2 两个2的位置交换了
按年龄排序 有可能交换位置