• Day 06 python学习笔记


    常见排序算法

    先简单讲解一下如何交换两个变量的值

    1. 创建临时变量
    2. 直接交换(a,b = b,a)
    1. 例:
    2. 临时变量:
    3. c = a
    4. a = b
    5. b = c
    6. #直接交换
    7. a , b = b , a

    冒泡排序

    两两比较,找最大值换到最后,再找次大值,放次之

    以下以找最大值为例子:

    1. # 冒泡排序 大数上浮法、小数下沉法(每次找最小值往最前边排或每次找最大值往最后排)
    2. arr = [30,8,-10,22,26,3,2,9,11]
    3. def bubble_sort(arr):
    4. for i in range(0, len(arr)-1): #为了控制比较操作的循环次数
    5. for j in range(0, len(arr)-1-i): #选择操作的元素(索引下标)
    6. if arr[j] >= arr[j+1]:
    7. arr[j], arr[j+1] = arr[j+1], arr[j]
    8. else:
    9. pass #空语句,防止报错
    10. return arr
    11. if __name__ == '__main__': #python的main函数 防止被别的模块导入时执行
    12. a = bubble_sort(arr)
    13. print(a)
    14. 结果:
    15. [-10, 2, 3, 8, 9, 11, 22, 26, 30]

    图解:

    选择排序

    每次找最小值,以假设最小值进行位置互换。(循环后面全部找出最小值后换)
    [30,8,-10,22,26,3,2,9,11]
    第一次 假设30最小,在其他当中找最小值,即-10,进行位置互换
    [-10,8,30,22,26,3,2,9,11]
    第二次 假设8最小,在其他当中找最小值,即2,进行位置互换
    [-10,2,30,22,26,3,8,9,11]

    1. # 选择排序
    2. # 类似于冒泡排序,每一次找到最小值
    3. arr = [8,3,2,6,1,4,9,7]
    4. def xuanze(arr):
    5. for i in range(0, len(arr)-1): #控制循环的次数(即开始的起点)
    6. min = i #假定第一个为最小值(创建个临时变量)
    7. for j in range(i+1, len(arr)): #从开始起点循环到结束
    8. if arr[j] < arr[min]: #如果小则交换,将下标交换
    9. min = j
    10. if i != min: #循环结束,判断是否后面有小值,有则交换
    11. arr[i], arr[min] = arr[min], arr[i]
    12. return arr
    13. if __name__ == '__main__':
    14. a = xuanze(arr)
    15. print(a)
    16. 结果:
    17. [1, 2, 3, 4, 6, 7, 8, 9]

    插入排序

    默认第一个值为有序的,之后一次插入后面的每一个值(多次比较),最终得出排序结果。保证 前面的数都是有序

    例:

    [6,5,3,8,7,2,4]

    第一次 假设第一位(6)有序(最小),将后一位(第二位)与第一位对比,若第二位小将其插入到第一位前作为第一位

    [5,6,3,8,7,2,4]

    第二次 假设前两位有序,将后一位(第三位)与第二位对比,若比第二位小,再与第一位对比,若比第一位大比第二位小则将其插入到第二位前作为第二位,反之若比第一位小则将其插入到第一位前作为第一位

    [3,5,6,8,7,2,4]

    第三次 假设前三位有序,将后一位(第四位)与第三位对比,,若比第三位大,则保持原位,默认前四位有序,若比第三位小,再与第二位和第一位(前面有序的全部)对比,若比第二位大比第三位小则将其插入到第三位前作为第三位,反之若比第一位大比第二位小则将其插入到第二位前作为第二位,若比第一位小则将其插入到第一位前作为第一位

    [3,5,6,8,7,2,4]

    1. #插入排序
    2. num = [11,2,12,13,1,4]
    3. def insert_sort(num):
    4. for i in range(0, len(num)-1): #默认有序下标(i前包括i全部有序)
    5. for j in range(i+1, 0, -1): #i+1 往前比较
    6. if num[j] < num[j-1]:
    7. num[j], num[j-1] = num[j-1], num[j]
    8. return num
    9. insert_sort(num) #函数调用
    10. print(num)

    计数排序

    计数排序(Counting Sort)是一种不比较数据大小的排序算法,是一种牺牲空间换取时间的排序算法

    计数排序适合数据量大且数据范围小的数据排序,如对人的年龄进行排序,对考试成绩进行排序等

    找到待排序列表中的最大值 k,开辟一个长度为 k+1 的计数列表

    例(元素不重复):

    原容器:

    arr  = [2,3,1,6,5,7]

    创建新容器(7+1)

    arr0 = [0, 0, 0, 0, 0, 0, 0, 0] 

    下标    0  1  2  3  4  5  6  7

    然后找与元素相同的下标值元素加1(两个就是2)

    arr0 = [0, 1, 1, 1, 0, 1, 1, 1]

    然后再将为1的导出

    ==>    [1,2,3,5,6,7]   即排序成功

    1. #计数排序
    2. def counting_sort(array): #如果只有一个数无需排序直接返回
    3. if len(array) < 2:
    4. return array
    5. max_num = max(array)
    6. count = [0] * (max_num + 1) #创建一个新列表,记录下标索引
    7. for num in array: #寻找是否有元素相同的下标值,有则加一,并统计每个值的数量
    8. count[num] += 1
    9. new_array = list() #创建空列表导出
    10. for i in range(len(count)): #循环次数(遍历列表全部)
    11. for j in range(count[i]): #循环次数(相同元素的数量)
    12. new_array.append(i) #将元素i加入new_array
    13. return new_array
    14. if __name__ == '__main__':
    15. array = [5, 7, 3, 7, 2, 3, 2, 5, 9, 5, 7, 6]
    16. print(counting_sort(array))
    17. 结果:
    18. [2, 2, 3, 3, 5, 5, 5, 6, 7, 7, 7, 9]

    二分查找

    二分查找(折半查找):在有序序列中高效的查找指定的元素

    1. #二分查找
    2. def binary_search(list,item):
    3. """二分查找方法"""
    4. left = 0 # 定义最小下标
    5. right = len(list)-1 # 定义最大下标
    6. while left <= right: #while循环,保证可以遍历到指定区域的元素,直到被被寻找的值和中间值相等
    7. mid = int((left + right)/2) # 寻找数组的中间值
    8. guess = list[mid] # 获取列表最中间的元素
    9. if guess == item:
    10. return mid # 进行条件判断,将中间值和被寻找的值进行比较,相等则返回该值
    11. if guess > item:
    12. right = mid-1 # 如果被寻找的值小于中间值,则最大下标变化为中间值的前一个元素下标
    13. else:
    14. left = mid + 1 # 如果被寻找的值大于中间值,则最小下标变化为中间值的后一个元素下标
    15. return None
    16. nums = [1,33,44,66,77,567,5677]
    17. print(binary_search(nums,567))
    18. 结果:
    19. 5 #返回索引下标

    函数

    组织好的,可以重复使用的,用于实现特定功能的代码块

    len(name)内置函数 len 官方写好的 input print。。。。都是内置函数

    避免重复的进行代码书写,提高代码的复用率

    函数的定义语法

    1. 格式:
    2. def 函数名(参数1,参数2......):
    3. 函数体
    4. return 语句
    5. #return:返回函数的返回值
    6. #return后边的代码不会再执行了哦
    7. #函数的返回值 将结果返回给调用者

    练习:

    1、定义一个函数,求其绝对值

    1. def my_abs(x):
    2. if x < 0:
    3. return -x
    4. else:
    5. return x
    6. a = my_abs(-3)
    7. print(a)
    8. a = my_abs(1)
    9. print(a)
    10. 结果:
    11. 3
    12. 1

    2、定义函数,调用后输出“我叫XXX”

    1. def out():
    2. print("我叫XXX")
    3. b = out()
    4. print(b)
    5. c = out() #函数名可以赋值给变量
    6. c() #变量即为函数的别名,函数名+()是执行
    7. 结果:
    8. 我叫XXX
    9. None #函数无返回值
    10. 我叫XXX
    11. #None类型:NoneType的字面量,函数不使用return,返回的是None:返回值没有意义
    12. #None声明无意义的变量
    13. #name=None
    14. #在if判断中:None===False

    函数的传参

    函数的参数:函数进行计算时,接受外部(调用时)提供的数据

    传入参数的类型检查

    1. def my_abs(x):
    2. if not isinstance(x,(int,float)): #判断如果不是int与float类型报错
    3. raise TypeError ("i'am sorry") #raise 用于在报错最后显示
    4. if x < 0:
    5. return -x
    6. else:
    7. return x
    8. a = my_abs('a')
    9. print(a)
    10. 结果:
    11. Traceback (most recent call last):
    12. File "D:\pycharm\06-笔记.py", line 39, in
    13. a = my_abs('a')
    14. File "D:\pycharm\06-笔记.py", line 33, in my_abs
    15. raise TypeError ("i'am sorry")
    16. TypeError: i'am sorry #显示

    返回值

    事实上,函数返回的是一个元组,多个变量可以同时接收一个元组

    1. #返回值
    2. def sum_01():
    3. a = 1
    4. b = 2
    5. return a,b #同时返回多个值用 ,隔开即可(元组也可以省略外面的括号)
    6. a = sum_01() #因为只有一个接收变量,所以多个返回值会以元组的形式给他接收
    7. print(a)
    8. a,b = sum_01() #多个返回值会以元组的形式返回
    9. print(a)
    10. print(b)
    11. v,b,n = (3,4,5) #多个变量(与元组元素个数相同)接收元组,依次接收
    12. print(v)
    13. print(b)
    14. print(n)
    15. 结果:
    16. (1, 2)
    17. 1
    18. 2
    19. 3
    20. 4
    21. 5

    位置参数

    例:两个数字相加的函数的定义

    a,b:形式参数
    1,2:实际参数
    数量不受限制(但形式参数与实际参数数量不同会报错)

    形式参数与实际参数数量一致所以依次传递(即位置传参)

    1、数量必须与定义时一致
    2、位置必须与定义时一致

    默认参数

    1. def power(x, n=2):
    2. s = 1
    3. while n > 0:
    4. n = n - 1
    5. s = s * x
    6. return s
    7. a = power(1)
    8. print(a)
    9. 结果:
    10. 1

    默认值参数设置的注意点

    1. 必选参数在前,默认参数在后(原因:可以把必选的传入完后,后面全部默认)
    2. 多个参数时,把变化小的放在后面。变化小的参数就可以作为默认值参数
    3. 默认值只会执行一次

    好处:降低调用函数的难度

    默认参数的坑:

    1. def add_end(L=[]):
    2. L.append('END') #将END传入列表L
    3. return L
    4. add_end()
    5. add_end()
    6. 结果:
    7. ['END', 'END']
    8. ['END', 'END', 'END']

    第一次调用add_end()时没有错误,第二次时,就会出现函数似乎记住了第一次调用的函数添加的end的列表

    解释:

    函数在被定义的时候,默认参数b的值会被计算出来,即[ ],因为默认参数L也是变量,指向对象[ ].每次调用函数,如果改变了L里边的内容, 则在下一次调用时,默认参数的额内容也改变了

    所以:

    官方推荐:默认参数尽量使用不可变类型,原因在于可变对象会存储在后续调用过程中传递给他的参数

    解决方法:

    1. 例:
    2. def abc(a,b=None): #None不可变参数
    3. if b==None:
    4. b = []
    5. b.append(a)
    6. print(b)
    7. abc(100)
    8. abc(200)
    9. 结果:
    10. [100]
    11. [200]
     
    
  • 相关阅读:
    电脑性能参数了解
    用闪电侠的例子解释一下进程和线程
    美食杰项目 -- 个人主页(四)
    90行代码写一个视频播放器
    Python 编码规范 自用
    用户体验新尝试&思考|让“跳转”加速
    排列与二进制(暑假每日一题 33)
    盘点几种常用加密算法
    python学习笔记:引用、浅拷贝和深拷贝(底层原理)
    VMWare 虚拟机如何扩展磁盘空间并挂载到已存在的根目录
  • 原文地址:https://blog.csdn.net/Starry__Sky222/article/details/133701269