您现在的位置是:主页 > news > 营销型网站建设培训/百度指数app下载

营销型网站建设培训/百度指数app下载

admin2025/6/16 13:04:37news

简介营销型网站建设培训,百度指数app下载,重庆网站建设seo公司,廊坊网站制作报价第一章 认识算法 广义的算法:指做一件事情 / 解决一个问题的方法。 狭义的算法:数据结构控制流程。(实现算法就先确定数据结构,再明确控制流程,最后实现算法) 掌握算法的5个层次: 1、听说&…

营销型网站建设培训,百度指数app下载,重庆网站建设seo公司,廊坊网站制作报价第一章 认识算法 广义的算法:指做一件事情 / 解决一个问题的方法。 狭义的算法:数据结构控制流程。(实现算法就先确定数据结构,再明确控制流程,最后实现算法) 掌握算法的5个层次: 1、听说&…

第一章  认识算法

广义的算法:指做一件事情 / 解决一个问题的方法。

狭义的算法:数据结构+控制流程。(实现算法就先确定数据结构再明确控制流程最后实现算法

掌握算法的5个层次:

  • 1、听说:知道有这么个算法
  • 2、了解:知道算法的原理,用自然语言描述
  • 3、理解:知道算法的细节,数据结构和控制流程,时空复杂度
  • 4、实现:用编程语言实现
  • 5、应用:举一反三

算法的难点在于:从概括性的原理转换为具体数据结构,一步步实现对应的控制流程。

对于每个算法:我们要讲抽象原理,再将其拆解成数据结构和控制流程,详细推演整个运行过程的细节,将细节写成代码。

第二章  控制流程

顺序、条件、循环等几种控制流程

第三章  计算机是如何运行的

数据的基本概念、计算机的前世今生

第四章  万物的抽象:数据结构

数组、链表的基本概念

第五章  复杂一些的数据结构:图和树

图和树的基本概念

二叉树的深度优先遍历算法:

先序遍历、中序遍历、后序遍历实际上是先根序遍历、中根序遍历、后根序遍历。--- 主体:根节点

  • 先序遍历:先访问根节点
  • 中序遍历:中间访问根节点
  • 后序遍历:最后访问根节点

要求:

  • 把树拆成左子树、根、右子树三部分。
  • 将左子树、右子树分别作为两棵树,将他们分别按上一步拆分。
  • 直到一颗子树只有一个节点为止。

第六章  第一行python代码

python语言基本介绍

第七章  开始用python语言编写程序

python基本数据结构

第八章  实现一个算法衡量其优劣

查找算法的要素:待查集合、目标数。

第一个算法:顺序查找,无序查找,待查集合未排序。

算法原理:从前往后依次查找。

代码实现

while

tn = 95  # 目标数
arr = [1, 5, 8, 19, 3, 2, 14, 6, 8, 22, 44, 95, 78]  # 待查集合
i = 0  # 从头开始查找
while i < len(arr):if arr[i] == tn:print("success:", i)breakelse:i = i + 1
if i == len(arr):  # 循环退出条件print("failed")

for

tn = 95  # 目标数
arr = [1, 5, 8, 19, 3, 2, 14, 6, 8, 22, 44, 95, 78]  # 待查集合
for i in range(0, len(arr)):if arr[i] == tn:print("success:", i)break
if i == len(arr):  # 循环退出条件print("failed")

时间复杂度

运算速度的表达,标记为大O

空间复杂度

占据存储空间的大小,标记为大O

第九章  简单但有用的经典查找算法

从1~1000内任意选择一个数做为神秘数字,猜中结束

1、不限次数,可以从前往后找。

tn = 165
found = False
for i in range(1, 1001):if i == tn:print("success:", i)found = Truebreak
if not found:print("failed")

2、限制次数就要跳跃找。

首先要确定跳的方向,其次要确定跳的距离。确定这个思路后,二分查找就是一个不错的想法。

二分查找

有序序列中查找特定元素

arr = [3, 5, 7, 9, 12, 15, 18, 32, 66, 78, 84, 103, 209]  # 待查序列
tn = 5  # 目标数low = 0
high = len(arr) - 1  # 区域起始范围while low <= high:  # 待查区域存在m = int((high - low) / 2) + low  # 当前区域中间位置if arr[m] == tn:print("success:", m)else:if arr[m] < tn:low = m + 1else:high = m - 1
if low > high:print("failed")

第十章  程序中的函数

函数四要素:

  • 函数名:标识函数的名字
  • 参数:输入数据传递给函数的变量
  • 函数体:实现函数功能的代码块
  • 返回值:函数处理完返回给外界的值

将二分查找封装成函数:

def binary_search(arr, tn):low = 0high = len(arr) - 1while low <= high:m = int((high - low) / 2) + lowif arr[m] == tn:return melse: if arr[m] < tn:low = m + 1else:high = m - 1if low > high:return -1
arr = [3, 5, 7, 9, 12, 15, 18, 32, 66, 78, 84, 103, 209]  # 待查序列
tn = 5  # 目标数result = binary_search(arr, tn)
if result > 0:print("success:", result)
else:print("failed")

函数的作用主要有三个:

  • 重用:重复使用
  • 抽象:只需要知道功能,参数,返回值即可
  • 封装:将抽象的功能包装
arr = []  #生成arr
for i in range(0, 1001):arr.append(i)for tn in range(1, 1001):  # 1-1000的数都可以做一次二分查找result = binary_search(arr, tn)if result >= 0:print("success:", result)elseprint("failed")

函数参数的简化理解

  • 如果变量是基础类型,就算将它传给函数,调用完后,原值不变
  • 如果变量是列表类型,将其传给函数调用后,列表中内容改变。

第十一章  编程实现猜数游戏

low = 1
high = 1000  # 范围
loop_num = 0  # 初始循环次数为 0while low <= high:m = int((high - low) / 2) + lowloop_num += 1print("[Loop %s]: My guess is %s, and high is %s" % (loop_num, low, high))user_input = ""while user_input != '1' and user_input != '2' and user_input != '3':print("1) %s == sn 2) %s < sn 3) %s > sn." % (m, m, m))user_input = input("Your option: ")user_input = user_input.strip()if user_input == '1':print("Success: sn is :", m)breakelse:if user_input == '2':low = m + 1else:high = m - 1if low > high:print("failed")

防止bug危害的方法

  • 代码层:代码审查
  • 运行层:软件测试
  • 开发层:测试驱动开发,先写测试用例

第十二章  二分查找的变形

含有重复目标数组的二分查找,并确定重复目标数的头或者尾

def repeating_sequence_binary_search(arr, tn, delta):low = 0high = len(arr) - 1while low <= high:m = int((high - low) / 2) + lowif arr[m] == tn:  # 找到目标数之后根据delta确定寻找方向的数是否等于目标数while 0 <= m + delta < len(arr) and arr[m + delta] == tn:  # m+delta一定判断范围是否越界,and判断有先后顺序m += deltareturn melse:if arr[m] < tn:low = m + 1else:high = m - 1if low > high:return -1

在找到目标数之后,m + delta环节再做二分查找,快速找到头或尾元素

def quick_repeating_sequence_binary_search(arr, tn, delta):low = 0 high = len(arr) - 1while low <= high:m = int((high - low) / 2) + lowif arr[m] == tn:if 0 <= m + delta < len(arr) and arr[m + delta] == tn:if delta < 0:  # 在有某一个方向上的其他重复数等于tn的时候,直接在该方向做二分查找high = m - 1else:low = m + 1else:return melse:if arr[m] < tn:low = m + 1else:high = m - 1if low > high:return -1

旋转数列的二分查找

旋转数列的三种情况:

  • [14, 17, 29, -3, 0, 1, 5, 8, 12]     情况1:arr[m] < arr[low]
  • [5, 8, 12, 14, 17, 29, -3, 0, 1]     情况2:arr[m] > arr[high]
  • [-3, 0, 1, 5, 8, 12, 14, 17, 29]     情况3:arr[m] 是未经过旋转的有序数列

所有三种情况中,只要数列经过旋转所有arr[low] > arr[high]

情况1,如果找比 arr[m] 小的数字,只有左边一种可能

情况2, 如果找比 arr[m] 大的数字,只有右边一种可能

def binary_search_in_rotated_sequence(arr, tn):low = 0high = len(arr) - 1while low <= high:m = int((high - low) / 2) + lowif arr[m] == tn:return melse:if arr[m] < tn:  # 如果中间数比目标数小,寻找比m大的数if arr[m] < arr[low]:  # 第一种情况下,比m大的数有两种可能if arr[low] <= tn: # 1.如果low比目标数小,目标数一定在m左边high = m - 1else:              # 2.如果low比目标数大,目标数在m右边low = m + 1else:                  # 其他两种情况low = m + 1        # 比m大的数都在右侧else:                      # 如果中间数比目标数大,寻找比m小的数if arr[m] > arr[high]: # 第二种情况下,比m小的数有两种可能if arr[high] >= tn:# 1.如果high比目标数大,小的数在m右侧low = m + 1else:              # 2.如果high比目标数小,小的数在m左侧high = m - 1else:high = m - 1       # 其他两种情况小的数都在左侧if low > high:return -1

代码优化

def binary_search_in_rotated_sequence(arr, tn):low = 0high = len(arr) - 1while low <= high:m = int((high - low) / 2)+ lowif arr[m] == tn:return melse:if arr[m] < tn:                  # m 比 tn 小,找一个大的数if arr[m] < arr[low] <= tn:  # 只有第一种情况下比low大的数才向左找high = m - 1else:                        # 其他情况向右找low = m + 1else:                            # m 比 tn 大, 找一个小的数if arr[m] > arr[high] >= tn: # 只有第二种情况下比high小的数向右找low = m + 1                           else:high = m - 1             # 其他情况向左找  if low > high:return -1

包含重复元素的旋转数列二分查找

def binary_search_in_rotated_repeating_sequence(arr, tn, delta):low = 0high = len(arr) - 1if delta < 0 and arr[0] == tn:    # 头尾元素需要特殊处理,旋转的缘故,重复数存在头尾元素相同的情况return 0if delta > 0 and arr[-1] == tn:return len(arr) - 1while low <= high:m = int((high - low) / 2) + low if arr[m] == tn:if 0 <= m + delta < len(arr) and arr[m + delta] == tn:if delta < 0:high = m - 1else:low = m + 1else:return melse:if arr[m] < tn:if arr[m] < arr[low] <= tn:high = m - 1else:low = m + 1else:if arr[m] > arr[high] >= tn:low = m + 1else:high = m - 1if low > hgih:return -1    

第十三章  认识排序算法

排序就需要交换

def swap(arr, i, j):  # 在数组arr中,交换下标i和j的元素if len(arr) < 2:  # 长度小于2,不需要交换returnif i < 0 or i >= len(arr) or j < 0 or j >= len(arr):  # 超过下标范围,不需要交换returnif i == j:  # 下标相等,不需要交换returntmp = arr[i]arr[i] = arr[j]arr[j] = tmpreturn

第十四章  几种简单排序算法

选择排序

  • 从未排好序的数列中选择最小的数放在排好序的数列后面
def selection_sort(arr):for start_position in range(0, len(arr)):  # 从前往后遍历序列min_position = start_position          # 处理最小值设为开头for i in range(start_position + 1, len(arr)):   # 遍历剩余未拍好序列if (arr[i] < arr[min_position]):            # 将min_position设置到最小位置min_position = iswap(arr, start_position, min_position)         # 将当前循环下最小值交换到start_positonreturn

冒泡排序:

  • 从前往后或从后往前遍历未排好序列,两两比较交换,是最值上浮
def bubble_sort(arr):for i in range(0, len(arr)):  # 遍历整个序列swapped = False           # 设置交换标志位for j in range(len(arr) - 1, i, -1):  # 从后向前遍历未排好序队列if arr[j] < arr[j - 1]:           # 如果当前数比前一个数小swap(arr, j, j - 1)           # 交换swapped = True                # 设置交换标志位为trueif not swapped:                       # 如果未交换,说明已排好,跳出循环returnreturn

插入排序:

  • 从后面找一个数,遍历插入前面已排好序的队列中
def insertion_sort(arr):if len(arr) == 1:  # 长度等于1,不需要排序returnfor i in range(1, len(arr)):  # 默认第一个元素已排好序,从第二个元素开始遍历for j in range(i, 0, -1): # 0 ~ i是要进行插入排序的队列if arr[j] < arr[j - 1]:  # 如果存在后一个数比前一个数小,交换swap(arr, j, j - 1)else:break                # 否则认为已排好序,结束本次循环return

简单排序在数据量大的时候就可能面临性能问题。

第十五章  必须掌握的排序算法

快速排序,与二分查找并驾齐驱。

简单分区函数:

def partition(arr):  # 分治if len(arr) < 2:return arr, None, Noneleft_partition = []   # 定义左分区right_partition = []  # 定义右分区pivot = arr[0]        # 定义轴for i in range(1, len(arr)):  # 遍历轴以外的数列if arr[i] <= pivot:       # 小于等于轴,添加左分区left_partition.append(arr[i])else:fight_partition.append(arr[i])  # 反之,添加到右分区return left_partition, pivot, right_partition  # 返回左分区,轴,右分区

进行修改,使上述思路返回的还是一个列表

def partition(arr):  # 分区函数if len(arr) < 2:  return - 1left_partition = []  # 定义左分区right_partition = []  # 定义右分区pivot = arr[0]        # 定义轴for i in range(1, len(arr)):  # 遍历轴以外的所有元素if arr[i] <= pivot:left_partition.append(arr[i])   # 比轴小放左分区else:right_partition.append(arr[i])   # 比轴大放右分区arr[0:len(left_partition)] = left_partition[0:len(left_partition)]   #将左分区放到原数列arr[len(left_partition)] = pivot   # 轴放到原数列arr[len(letf_partition) + 1:len(arr)] = right_partition[0:len(right_partition)]  # 右分区放到原数列return len(left_partition)  # 分区之后轴的位置

再升级到任意区间:

def partition(arr, low , high):if low >= high:return -1left_partition = []right_partition = []pivot = arr[low]for i in rang(low + 1, high + 1):  # 遍历轴后的区间if arr[i] <= pivot:left_partition.append(arr[i])else:right_partition.append(arr[i])arr[low:low + len(left_partition)] = left_partition[0:len(left_partition)]arr[low + len(left_partition)] = pivotarr[low + len(left_partition) + 1:hight + 1] = right_partition[0:len(right_partition)]return low + len(left_aprtition)  # 返回轴的位置

再升级,压缩空间复杂度

def partition_v2(arr, low, high):  # 改进的分区算法if low >= high:return -1pi = low      # 用指针代替赋值给左右两个队列和轴li = low + 1ri = highwhile li <= ri:      # 两个指针没有出现错位if arr[li] > pi:       # 如果左边指针比轴大swap(arr, li, ri)  # 跟右边指针元素交换位置ri = ri - 1        # 右边指针向左else:                  li = li + 1        # 否则,不动,左边指针往右pi = li - 1                # 轴位置在左边指针减1的位置swap(arr, low, pi)         # 将low 和轴位置的值交换return pi                  # 返回轴位置

通过分区用分治的思想实现快速排序

用一个二维数组来表示待分的区域,迭代表示

[[a1, b1],

[a2, b2],

...

[an, bn]]

思路:一开始low和high之间为待分区间,第一次分出了左右两个区间,将这两个区间添加到二维数组,同样的方法对新的区间再分,再添加到二维数组中,直到不可分为止

def q_sort_iteration(arr, low, high):   # 迭代的方法if low >= high:returnregions = [[low, high]]    # 存放迭代的区域的二位数组i = 0while i < len(regions):    # 用数组长度控制循环low = regions[i][0]    # low是二位数组中一行第一个数high = regions[i][1]   # high是二位数组中一行中第二个数p = partition_v2(arr, low, high)   # 找到这一行的轴if p != -1:regions.append([low, p - 1])    # 以轴为单位划分区域regions.append([p + 1, high])i = i + 1return

第十六章  递归实现快速排序

递归的基本函数表示

在函数体内部调用函数本身

def recursion():recursion()return

限制递归次数

def recursion(depth):if depth < 1000:recursion(depth + 1)return

斐波那契数列

def fibonacci(n):if n < 0:print("invalid input")elif n == 0:return 0elif n == 1:return 1else:return fibonacci(n - 1) + fibonacci(n - 2)

递归实现快速排序

def qsort_recursion(arr, low, high):if low >= high:returnp = partition_v2(arr, low, high)qsort_recursion(arr, low, p - 1)qsort_recursion(arr, p + 1, high)return

第十七章  算法精进

算法的五个层次

  • 听说
  • 了解
  • 理解
  • 实现
  • 应用

例题:

实现一个函数,满足如下要求:输入一个正整数,输出也是正整数;输出值是与输入值平方根最近的那个数;整个过程只能用加减乘除,算法时间复杂度要求尽量小。

分析:

1、实现一个函数,函数四要素,函数名、参数、函数体、返回值

  • 函数名:目的,该函数是要求输入值平方根最近的整数,所以命名为closest_sort
  • 参数:输入是一个整数,命名为 n
  • 返回值:整数,由函数体中命名而来
  • 函数体:过程,如何实现函数的目的

2、不能开方,就找一个数的平方最接近输入值,找,就是查找算法,考虑二分查找

def closest_sqrt(n):if n <= 0:print("invalid input")return -1low = 1high = nwhile low <= high:m = int((high - low) / 2) + lowif m * m == n:return melif m * m < n < (m + 1) * (m + 1):if n - m * m > (m + 1) * (m + 1) - n:return m + 1else:return melse:if m * m > n:high = m - 1else:low = m + 1return -1