【Python】数据结构和算法基础到进阶

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

利用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)

三、排序

  1. 什么是列表排序?
    排序:将一组“无序”的记录序列调整为“有序”的记录序列。
    列表排序:将无序列表变为有序列表。
    输入:列表
    输出:有序列表
    内置函数:sort()
  2. 常见排序算法介绍:
  • low:冒泡,选择,插入
  • NB:快速,堆,归并
  • 其他:希尔,计数,基数
  1. 排序算法分析

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))
  • 分解: 将列表越分越小, 直至分成一个元素。
  • 终止条件: 一个元素是有序的。
  • 合并: 将两个有序列表归并,列表越来越大。

总结

可以使用图形帮助算法过程的理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值