提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
利用python实现常用的算法
提示:以下是本篇文章正文内容
一、递归
1、递归的两个特点
1. 调用自身
2. 结束条件
# 汉诺塔问题
def hanoi(n, a, b, c):
# n 有n个盘子
# a,b,c表示三个柱子
hanoi(n-1, a, c, b)
print("moving from %s to %s"%(a,c))
hanoi(n-1, b, a, c)
hanoi(3, "A", "B", "C")
二、列表查找
什么是列表查找?
查找:在一些数据元素中,通过一定方法找到与给定关键字相同的数据元素的过程。
列表查找(线性表查找):从列表中查找指定元素。
- 输入:列表,待查找元素
- 输出:元素下标(未找到时一般返回None,-1)
内置列表查找函数:index()
1.顺序查找 (linear search)
顺序查找也叫线性查找,从列表的第一个元素开始,顺序进行搜索,直到找到元素或者搜索到列表的最后一个元素为止。
代码如下(示例):
def linear_search(lst, val)
for ind, v in enumerate(lst):
if v == val:
return ind
else:
return None
2. 二分查找(binary search)
二分查找:又叫折半查找,从有序列表的初始候选区lst[0:n]开始,通过对待查找的值与候选区中间值的比较,可以使候选区减少一半。
注意:必须是有序列表。
候选区:查找元素的区间。
候选区的维护:用left,mid,right指针的移动。
代码如下(示例):
def binary_search(lst, val):
left = 0
right = len(lst) - 1
while left <= right:
mid = (left + right)//2
if lst[mid] == val:
return mid
elif lst[mid] > val: # 说明要查找的值在mid左侧
right = mid - 1
else: # lst[mid] < val 说明要查找的值在mid右侧
left = mid + 1
else:
return None
lst = [1,5,8,10,13,15,16,18,20]
binary_search(lst,20)
三、排序
- 什么是列表排序?
排序:将一组“无序”的记录序列调整为“有序”的记录序列。
列表排序:将无序列表变为有序列表。
输入:列表
输出:有序列表
内置函数:sort() - 常见排序算法介绍:
- low:冒泡,选择,插入
- NB:快速,堆,归并
- 其他:希尔,计数,基数
- 排序算法分析
3.1 冒泡排序
def bubble_sort(lst:list):
for i in range(len(lst)-1): # 第i趟
exchange = False
for j in range(len(lst)-i-1):
if lst[j] > lst[j+1]:
lst[j], lst[j+1] = lst[j+1], lst[j]
exchange = True
# print(lst)
if not exchange:
break
return lst
lst = [2,3,7,4,1,9,5,8,6,0]
print(lst)
print(bubble_sort(lst))
3.4 堆排序
3.4.1 树与二叉树
- 树是一种数据结构
- 树是一种可以递归定义的数据结构
- 树是由n个节点组成的集合:
如果n=0, 那这是一颗空树;
如果n>0, 那存在1个节点作为树的根节点,其他节点可以分为m个集合,每个集合本身又是一棵树。 - 一些概念:
根节点,叶子节点
树的深度(高度)
树的度:节点往下分叉的个数
孩子节点、父节点
子树 - 二叉树:度不超过2的树
每个节点最优有两个孩子节点
两个孩子节点被区分为左孩子节点和右孩子节点 - 满二叉树:一个二叉树,如果每一个层的节点数都达到最大值,则这个树是满二叉树。
- 完全二叉树:叶节点只能出现在最下层的次下层,并且最下面一层的节点都集中在该层最左边的若干位置的二叉树。
- 二叉树的存储方式(表示方式)
链式存储方式
顺序存储方式
3.4.2 堆
- 堆:一种特殊的完全二叉树结构
大根堆:一课完全二叉树,满足任一节点都比其孩子节点大
小根堆:一颗完全二叉树,满足任一节点都比其孩子节点小 - 堆的向下调整
当根节点的左右子树都是堆时,可以通过一次向下的调整来将其变换成一个堆。
3.4.3 堆排序过程
- 1 建立堆。
- 2 得到堆顶元素,为最大元素。
- 3 去掉堆顶,将堆最后一个元素放到堆顶,此时可以通过一次调整重新使堆有序。
- 4 堆顶元素为第二大元素。
- 5 重复步骤3,直到堆变空。
3.5 归并排序
- 假设现在的列表分两段有序,如何将其合称为一个有序列表?
- 这种操作称为一次归并。
def merge(li, low, mid, high):
i = low
j = mid + 1
ltmp = []
while i <= mid and j <= high: # 只要左右两边都有数
if li[i] < li[j]:
ltmp.append(li[i])
i += 1
else:
ltmp.append(li[j])
j += 1
# while 执行完,肯定有一部分没数了
while i <= mid:
ltmp.append(li[i])
i += 1
while j <= high:
ltmp.append(li[j])
j += 1
li[low:high+1] = ltmp
return li
li=[1,4,6,9,2,5,8,10]
print(merge(li,0,3,7))
- 分解: 将列表越分越小, 直至分成一个元素。
- 终止条件: 一个元素是有序的。
- 合并: 将两个有序列表归并,列表越来越大。
总结
可以使用图形帮助算法过程的理解。