同时微分可以理解为将导数转为
解释图片:
注意:
其中푑푦与函数增量∆푦之差就是표(∆푥)
首先确认一个性质:
函数푓(푥)在点푥0处可微的充分必要条件是푓(푥)在푥0处可导
两者的概念很相似:
但是在理解上可以把
1.导数理解为是描述函数变化的快慢,导数是函数的局部性质,一个函数在某一点的导数描述了这个函数在这一点附近的变化率。
2.微分理解为是描述函数变化的程度,微分是一个函数表达式,用于自变量产生微小变化时计算因变量的近似值。
或者把微分理解成是一个线性函数,那么导数就是微分的商
微分是dy=f’(x)dx 而导数是dy/dx
通过微分概念 求近似值:
1.1 一阶微分(1)一阶微分的形式不变性
注意:形式不变性只适用于一阶微分
(2)常用微分公式(和导数非常像)
简单的说:导数还可以导,导几次就是几阶导数:
定义:
注意:n次多项式最高阶导是n次
例子:
(1)简单四则运算:
(2)莱布尼兹公式:
例子:
排序算法的稳定性是相对于字典(哈希表)的,即当键值被排序后,相同键值的相对位置不能被改变
稳定性:稳定排序算法会让原本有相等键值的纪录维持相对次序。
例子:
冒泡排序
实际上是把大的数不断下沉的过程,一次遍历下沉一个数,所以n个数需要n-1次遍历(n-1是因为沉底到最后剩一个的情况不用再排了),即遍历两次
首先考虑把一个元素沉底的情况:
# 先试着写把把一个最大数移到尾部的过程
for j in range(len(items) - 1):
if items[j] > items[j + 1]:
items[j], items[j + 1] = items[j + 1], items[j]
然后考虑不断沉底,即不考虑已经沉底的元素(即len-1-i,i表示已经沉底的元素)的情况下,对其他元素再进行上述操作,所以需要对每一个需要沉底的元素都遍历一次这样的操作
正向的写法:
def bubble_sort(items):
len_items = len(items)
for i in range(len_items-1):
for j in range(len_items - 1 - i):
if items[j] > items[j + 1]:
items[j], items[j + 1] = items[j + 1], items[j]
print(items)
反向的写法:
def bubble_sort_inverse(items):
len_items = len(items)
# 先判断每一次沉底需要几次操作
for j in range(len_items - 1, 0, -1):
# 然后直接对前j个元素进行j次操作来沉底一个元素
for i in range(j):
if items[i] > items[i + 1]:
items[i], items[i + 1] = items[i + 1], items[i]
优化:假如对于一个有序数组进行冒泡排序,我们希望第一次沉底之后,发现没有出现任何交换就可以跳出,从而减少程序运行时间。
def bubble_sort_opt(items):
len_items = len(items)
count = 0
for i in range(len_items - 1):
for j in range(len_items - 1 - i):
if items[j] > items[j + 1]:
count += 1
items[j], items[j + 1] = items[j + 1], items[j]
if count == 0:
print("本身有序,退出")
break
print(items)
从稳定性考虑:冒泡排序是稳定的
最好时间复杂度:优化后为O(n)
最坏时间复杂度:O(n2)
它的工作原理:
首先将序列分成两个部分:[已排序序列,未排序序列]
第一次遍历的时候,没有已排序序列,所以整个序列都是未排序序列,然后在未排序序列中找到最小(大)元素,然后放到开头,作为已排序序列的头部。
然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
实现:
def selection_sort(items):
len_items = len(items)
# 相当于把一个数组分为两部分([已排序,未排序]),然后从未排序的数组中一直选择,找到最小值放到已经排序的数组中去
# 把所有元素进行如此排序:
for j in range(len_items - 1):
min_index = j
for i in range(j + 1, len_items, 1):
if items[i] < items[min_index]:
min_index = i
# 然后把找到最小的元素和已排序数列的末尾+1元素进行交换
items[j], items[min_index] = items[min_index], items[j]
print(items)
if __name__ == "__main__":
items1 = [54, 226, 93, 17, 77, 31, 44, 55, 20]
selection_sort(items1)
从稳定性考虑:选择排序是不稳定的
最好时间复杂度:O(n2)
最坏时间复杂度:O(n2)
(1)工作原理:
首先将序列分成两个部分:[已排序序列,未排序序列]
1.每一次排序的过程是把未排序序列的第一个元素插入到已排序的序列中去。
2.把未排序的第一个元素i,在已排序序列(0到i-1)中从后向前扫描,找到相应位置并插入。(这个过程相当于把0到i的元素进行一次沉底)
(2)实现:
def insert_sort(items):
len_items = len(items)
# 确定当前元素i 确定已排序序列的尾部下标i-1
for i in range(1, len_items):
# 当前元素是items[i],把items[i]插入到前项元素中去,所以相当于从i开始往前走到头部,一个个排。
for j in range(i, 0, -1):
if items[j] < items[j - 1]:
items[j], items[j - 1] = items[j - 1], items[j]
print(items)
if __name__ == "__main__":
items1 = [54, 226, 93, 17, 77, 31, 44, 55, 20]
insert_sort(items1)
(3)优化:当插入元素和有序数列前一个比较,发现大于时,就直接跳出不走了,因为前面的数列有序,当插入元素大于前一个时,那之前的也都不用看了
def insert_sort(items):
len_items = len(items)
# 确定当前元素i 确定已排序序列的尾部下标i-1
for i in range(1, len_items):
# 当前元素是items[i],把items[i]插入到前项元素中去,所以相当于从i开始往前走到头部,一个个排。
for j in range(i, 0, -1):
if items[j] < items[j - 1]:
items[j], items[j - 1] = items[j - 1], items[j]
else:
break
print(items)
if __name__ == "__main__":
items1 = [54, 226, 93, 17, 77, 31, 44, 55, 20]
insert_sort(items1)
对比:
一个跑36次,一个跑31次,结果是一致的。
(4)
从稳定性考虑:选择排序是稳定的
最好时间复杂度:优化后为O(n)(升序排列,序列已经处于升序状态)
最坏时间复杂度:O(n2)



