人工智能3.5 -- python算法篇(五)排序和查找

python3调用腾讯AI开放平台 优快云上偶遇一文说明如何调用腾讯AI开放平台API,因为喜欢python3,所以用python3实现了下。用qq登录获取自己的id和key。参考点击打开链接。首先获取请求参数。新建了个文件md5sign.py。import hashlib   import time   import random   import string   from urllib.parse import quote ... 阅读详情

python,大数据,机器学习,深度学习,计算机视觉

三、python算法篇(五)排序和查找

前言 ---- 排序算法的稳定性

一个例子说明白!
比如,对这几个元组(4, 1) (3, 1) (3, 7) (5, 6),按照第一个元素的大小对他们进行排序,由于(3, 1)和(3, 7)的第一个元素是相等的,所以有下面两种排序结果:
(1)(3, 1) (3, 7) (4, 1) (5, 6) (维持原有次序)----- 稳定
(2)(3, 7) (3, 1) (4, 1) (5, 6) (原有次序被改变) ----- 不稳定
我们称第(1)种维持原有次序的排序算法是稳定的,而第(2)种改变了原有次序的排序算法是不稳定的。

同理:若原次序为 (4, 1) (3, 7) (3, 1) (5, 6),对其排序,则排序结果:
(1)(3, 7) (3, 1) (4, 1) (5, 6) (维持原有次序)----- 稳定
(2)(3, 1) (3, 7) (4, 1) (5, 6) (原有次序被改变) ----- 不稳定

1. 冒泡排序

自己画了个图,便于彻底理解!不必死记用背
请添加图片描述

(1)基本写法。下面这种写法太简单!不多说

09_bubble_sort.py代码:

def bubble_sort(alist):
	"""冒泡排序"""
	n = len(alist)
	"""j控制循环次数。共n-1次"""
	for j in range(1, n): # 表1 ~ n-1,总共冒泡n-1次。 ||或写 range(0, n-1):即ragne(n-1):但下面要改成for i in range(n-1-j):即for i in range(0, n-1-j):
		"""i控制下标/游标。从0开始,第一次一直移动到第n-1个元素(倒数第二个元素)即下标n-1-1即可,因为自然会取到第n个元素(最后一个元素)下标n-1"""
		for i in range(n-j): # 即range(0, n-j):表0 ~ n-j-1
			if alist[i] > alist[i+1]:
				alist[i], alist[i+1] = alist[i+1], alist[i] #python专有的交换语法

#test
if __name__ == "__main__":
	li = [54, 23, 32, 324, 34, 324, 3]
	print(li)
	bubble_sort(li)
	print(li)

思考:
想想若本来就是有序的序列[1, 2, 3, 4, 5, 6, 7],还要再都依次比较吗?
再想想若除了前两个元素其他都是有序的序列[2, 1, 3, 4, 5, 6, 7],还要这么写吗?

(2)改进的冒泡排序。----- 可处理一开始就是有序 或者 排序过程中的某次就已经是有序的

写法一:

def bubble_sort(alist):
	"""冒泡排序"""
	n = len(alist)
	"""j控制循环次数。共n-1次"""
	for j in range(n-1): #每次外层for循环开始,标记号count都重置为0
		count = 0
		"""i控制下标/游标。从0开始,第一次一直游标到倒数第二个元素(第n-1个元素)即下标n-1-1即可,因为自然会取到最后一个元素(第n个元素)下标n-1"""
		for i in range(0, n-1-j): #若内层for循环有过交换,则count+1
		# 即:for i in range(n-1-j): 
			if alist[i] > alist[i+1]:
				alist[i], alist[i+1] = alist[i+1], alist[i] #python专有的交换语法
				count += 1 # python不能写count++
		if 0 == count: #若没有过交换,即顺序是排好了的,则不需再遍历了。
			return


#test
if __name__ == "__main__":
	li = [54, 23, 32, 324, 34, 324, 3]
	print(li)
	bubble_sort(li)
	print(li)

写法二:

def bubble_sort(alist):
	"""冒泡排序"""
	n = len(alist)
	"""j控制循环次数。共n-1次"""
	for j in range(n-1): #每次外层for循环开始,标记号count都重置为0
		swap = False
		"""i控制下标/游标。从0开始,第一次一直游标到倒数第二个元素(第n-1个元素)即下标n-1-1即可,因为自然会取到最后一个元素(第n个元素)下标n-1"""
		for i in range(0, n-1-j): #若内层for循环有过交换,则count+1
		# 即:for i in range(n-1-j): 
			if alist[i] > alist[i+1]:
				alist[i], alist[i+1] = alist[i+1], alist[i] #python专有的交换语法
				swap = True # 交换过
		if swap == False: #若没有过交换,即顺序是排好了的,则不需再遍历了。
			return


#test
if __name__ == "__main__":
	li = [54, 23, 32, 324, 34, 324, 3]
	print(li)
	bubble_sort(li)
	print(li)

最优时间复杂度:O(n) ------ 遍历一次发现没有任何可以交换的元素,排序结束
最坏时间复杂度:O(n2)
算法稳定性:稳定 ----- 前面讲的能维持原有次序

2. 选择排序

根本思路:不断地找出相对最小的数,放到开头。
实现过程:
如 li = [54, 23, 32, 324, 34, 324, 3]
首先,默认第一个元素li[0] = 54是最小的数,记录下标min_index = 0(实际代码记录下标,列表/数组就是玩下标的)
然后,其他的元素都和最小数比较,谁更小就重定谁是最小数:
比到第23时,最小数成了23,记录其下标min_index = 1
再往后走,324…和最小数23比较…,一直到3出现,最小数成了3,记录其下标min_index = 6
所以将最小数放到最左边开头,即交换 li[6] 和 li[0]
此为一轮。
接着,不管li[0],再将li[1]看出最小的数,重复上面操作,进行几轮操作。如下:

一轮:li = [3,                    23, 32, 324, 34, 324, 54]
二轮:li = [3, 23,                32, 324, 34, 324, 54]
三轮:li = [3, 23, 32             324, 34, 324, 54]
四轮:li = [3, 23, 32, 34         324, 324, 54]
五轮:li = [3, 23, 32, 34, 54    324, 324]
六轮:li = [3, 23, 32, 34, 324, 324]

代码思路:
(1)初步代码设计:

def select_sort(alist):
	n = len(alist)
	min_index = 0
	for i in range(1,n):# j: 1 ~ n-1
		if alist[min_index]>alist[i]:
			min_index = i
	alist[min_index], alist[i] = alist[i], alist[min_index]

其实也可以按下面这样设计,但不如上面的效率高,因为alist[min_index], alist[i] = alist[i], alist[min_index]交换是执行两步(其他语言temp那种交换就是三步),前面已说过,列表(如同其他数组)就是玩下标的。
参考:

def select_sort(alist):
	n = len(alist)
	min_index = 0
	for i in range(1,n):# j: 1 ~ n-1
		if alist[min_index]>alist[i]:
			alist[min_index], alist[i] = alist[i], alist[min_index]

(2)进一步地:

def select_sort(alist):
	n = len(alist)
	for j in range(n-1):
		min_index = j
		for i in range(j+1, n):
			if alist[min_index] > alist[i]:
				min_index = i
		alist[j], alist[min_index] = alist[min_index], alist[j]

完整代码如下:
10_select_sort.py代码:

def select_sort(alist):
	"""选择排序"""
	n = len(alist)
	for j in range(n-1): # 即range(0, n-1) 故j: 0 ~ n-2
		min_index = j
		for i in range(j+1, n):
			if alist[min_index] > alist[i]:
				min_index = i
		alist[j], alist[min_index] = alist[min_index], alist[j]

#test
if __name__ == "__main__":
	li = [54, 23, 32, 324, 34, 324, 3]
	print(li)
	select_sort(li)
	print(li)

最优时间复杂度:O(n2) ------ 即使是排序好的有序序列也是O(n2)
最坏时间复杂度:O(n2)
算法稳定性:不稳定 ----- 有重复值时,考虑升序每次选择最大的情况

3. 插入排序

插入排序和选择排序一样都是分成左右两部分:左边(下标较小的)是排好序的,右边(下标较大的))是无序的。
不同的是:
上面选择排序是从右边选出最小值放到左边。
而插入排序是从右边随便拿一个,实际操作也就是一个个依次拿,和左边的去比较,排序插入到左边。即插入排序名字由此而来!

(1)基本写法。

代码思路:
(1)初步代码设计:

def insert_sort(alist):
	j = 1 # i = [1, 2, 3, ..., n-1]
	# 执行从右边的无序序列中取出第一个元素,即i位置的元素,然后将其插入到前面的正确位置中
	# 从第i个元素开始向前比较,如果小于前一个元素,交换
	for i in range(j, 0, -1): # j:从i ~ 1,递减。如range(5, 0, -1)是[5,4,3,2,1],最后位是1不是0,最后位 = 0-步长 = 0-(-1) = 1
		if alist[i] < alist[i-1]:
			alist[i], alist[i-1] = alist[i-1], alist[i]

(2)进一步地:

def insert_sort(alist):
	n = len(alist)
	for j in range(1, n):# j = [1, 2, 3, ..., n-1]
		# 执行从右边的无序序列中取出第一个元素,即i位置的元素,然后将其插入到前面的正确位置中
		# 从第i个元素开始向前比较,如果小于前一个元素,交换
		for i in range(j, 0, -1): # j:从i ~ 1,递减。如range(5, 0, -1)是[5,4,3,2,1],最后位是1不是0,最后位 = 0-步长 = 0-(-1) = 1
			if alist[i] < alist[i-1]:
				alist[i], alist[i-1] = alist[i-1], alist[i]

完整代码如下:
11_insert_sort.py代码:

def insert_sort(alist):
	""""插入排序"""
	n = len(alist)
	for j in range(1, n):# j = [1, 2, 3, ..., n-1]
		# 执行从右边的无序序列中取出第一个元素,即i位置的元素,然后将其插入到前面的正确位置中
		for i in range(j, 0, -1): # j:从i ~ 1,递减。
			if alist[i] < alist[i-1]:
				alist[i], alist[i-1] = alist[i-1], alist[i]

#test
if __name__ == "__main__":
	li = [54, 23, 32, 324, 34, 324, 3]
	print(li)
	insert_sort(li)
	print(li)
(2)改进的插入排序。----- 可处理一开始就是有序 或者 排序过程中的某次就已经是有序的

代码思路:
(1)初步代码设计:

def insert_sort(alist):
	"""插入排序"""
	i = 1 # i = [1, 2, 3, ..., n-1]
	while i > 0:
		if alist[i] < alist[i-1]:
			alist[i],alist[i-1] = alist[i-1], alist[i]
			i -= 1
		else:
			break

(2)进一步地:

def insert_sort(alist):
	n = len(alist)
	for j in range(1, n): # j = [1, 2, 3, ..., n-1]
		i = j # i 代表内存循环起始值
		# 执行从右边的无序序列中取出第一个元素,即i位置的元素,然后将其插入到前面的正确位置中
		while i > 0:
			if alist[i] < alist[i-1]:
				alist[i], alist[i-1] = alist[i-1], alist[i]
				i -= 1
			else:#如果a[i]比左边a[i-1]大,则退出本次while循环,想想[1,2,3,4,5]的情况。
				break

完整代码如下:
11_insert_sort.py代码:

def insert_sort(alist):
	"""插入排序"""
	n = len(alist)
	for j in range(1, n): # j = [1, 2, 3, ..., n-1]
		i = j # i 代表内存循环起始值
		# 执行从右边的无序序列中取出第一个元素,即i位置的元素,然后将其插入到前面的正确位置中
		while i > 0:
			if alist[i] < alist[i-1]:
				alist[i], alist[i-1] = alist[i-1], alist[i]
				i -= 1
			else:
				break

#test
if __name__ == "__main__":
	li = [54, 23, 32, 324, 34, 324, 3]
	print(li)
	insert_sort(li)
	print(li)

最优时间复杂度:O(n)----- 升序排列,序列已经处于升序状态
最坏时间复杂度:O(n2)
稳定性:稳定

4. 希尔排序

希尔排序和插入排序差不多,唯一的区别是希尔排序有步长。
首先步长gap设计为4,
第一组:下标为0,4, 8的拿出来分成一组(步长gap=4,所以0,4,8)
第二组:下标为1,5, 的拿出来分成一组
第三组:下标为2,6, 的拿出来分成一组
…
然后每组组内用插入排序算法比较。
在这里插入图片描述在这里插入图片描述在这里插入图片描述
接下来将步长gap设计为2,再重复步骤,同上(我们暂时用折半的方法取步长值)
在这里插入图片描述
在这里插入图片描述在这里插入图片描述最后,直到gap=1时,再用插入排序法,结束。
在这里插入图片描述看似麻烦,实则若gap设计好(实际中怎么给gap最优设计需要通过数学计算得到),效率很高。

代码思路:
(1)首先考虑核心代码,开始步长gap=1时,

#第一步 gap = 1
if alist[i] < alist[i-1]:
	alist[i], alist[i-1] = alist[i-1], alist[i]
else:
	break

(2)进一步地,gap = 2,4,8等。
完整代码如下:
12_shell_sort.py代码:

def shell_sort(alist):
	"""希尔排序"""
	n = len(alist)
	# gap具体怎么取会影响效率,最优取法要通过数学运算来算出,这里不研究,下面暂时用折半的方法(如第一次取4,下一次取2,再下一次取1)取gap值
	gap = n//2 # 除法运算。python3 n/2得到小数,n//2得到整数。而老版本的python2可以写n/2得到整数
	
	# gap变化到0之前,插入算法执行的次数
	while gap > 0:
		for j in range(gap, n): # 希尔排序,与普通的插入算法的区别就是gap步长
			# j = [gap, gap+1, gap+2, gap+3,..., n-1]
			i = j
			while i > 0:
				if alist[i] < alist[i-gap]:
					alist[i], alist[i-gap] = alist[i-gap], alist[i]
					i -= gap
				else:
					break
		# 缩短gap步长
		gap //= 2


#test
if __name__ == "__main__":
	li = [54, 23, 32, 324, 34, 324, 3]
	print(li)
	shell_sort(li)
	print(li)

注:可以对比一下插入排序的代码,对比理解和记忆。
最优时间复杂度:O(n1.3) ;根据步长(上面的gap)序列的不同而不同
最坏时间复杂度:O(n2) ------- gap直接取1的时候,就是插入排序
稳定性:不稳定 ------ 假设排序序列中有两个相同又相邻的数77和77,因为分成多组,第一个77被分到的那组有可能在组里面是最大值或相对较大的排序到后面,而第二个77分到的组如果其在组里是最小值或相对比较小的被排序到了前面,这样一来最终结局就是原来的第一个77跑到了第二个77后面,所以不稳定

5. 快速排序(重点,必须掌握)

快排一句话:序列中任意取一个元素作为目标(中间值mid_value),其余元素比他小的放到他左面,比他大的放到右面。然后左右两面重复上面操作,再取一个中间值…
【分析】:
第一步:

def quick_sort(alist, first, last): # ([54, 23, 32, 324, 34, 324, 3], 0, 6)

    mid_value = alist[first]
    left = first
    right = last

# 代码核心思想:
    # 比中间值(mid_value)小的放在左边(left),比中间值大的放在右边(right)。
    while left < right:
        alist[left] = alist[right]
        alist[right] = alist[left]

    # 从上面循环退出时,left == right
    alist[left] = mid_value

# 递归:
    # 对left左边的列表执行快速排序
    quick_sort(alist, first, left-1)
    # 对left右边的列表进行快速排序
    quick_sort(alist, left+1, last)

第二步:

def quick_sort(alist, first, last): # ([54, 23, 32, 324, 34, 324, 3], 0, 6)
    """快速排序"""

    if first >= last:
        return

    mid_value = alist[first] # 54
    left = first # 0
    right = last # 6
    
    # 比中间值(mid_value)小的放在左边(left),比中间值大的放在右边(right)。
    while left < right: # 0 < 6
        # 只要右边的比中间值大,right就一直左移:因为要从右向左找比中间值小的放到左边left里。
        while left < right and alist[right] >= mid_value:
            right -= 1
        alist[left] = alist[right]

        # 只要左边的比中间值小,left就一直右移:因为要从左向右找比中间值大的放到右边right里。
        while left < right and alist[left] < mid_value:
            left += 1
        alist[right] = alist[left]


    # 从上面循环退出时,left == right
    alist[left] = mid_value

    # 对left左边的列表执行快速排序
    quick_sort(alist, first, left-1) # 递归思想

    # 对left右边的列表进行快速排序
    quick_sort(alist, left+1, last)


#test
if __name__ == "__main__":
    li = [54, 23, 32, 324, 34, 324, 3]
    print(li)
    quick_sort(li, 0, len(li)-1)
    print(li)

完整代码如下,也可将left写成low低位、right写成high高位:
13_quick_sort.py代码:

def quick_sort(alist, first, last):
	"""快速排序"""

	if first >= last:
		return

	mid_value = alist[first]
	low = first
	high = last
	while low < high:
		# high左移
		while low < high and alist[high] >= mid_value:
			high -= 1
		alist[low] = alist[high]

		# low右移
		while low < high and alist[low] < mid_value:
			low += 1
		alist[high] = alist[low]
	# 从循环退出时,low == high
	alist[low] = mid_value

	# 对low左边的列表执行快速排序
	quick_sort(alist, first, low-1)

	# 对low右边的列表进行快速排序
	quick_sort(alist, low+1, last)


#test
if __name__ == "__main__":
	li = [54, 23, 32, 324, 34, 324, 3]
	print(li)
	quick_sort(li, 0, len(li)-1)
	print(li)

最优时间复杂度:O(nlogn) ------ 第一次分成左右两组,左右总共执行n次;第二次再分成22=4组,共执行n次;第三次分成22*2=8组,共执行n次…,直到不可再分割时即每组只有一个元素时。可见总共分割了log2n次(简记作logn),每次执行了n次,所以最优时间复杂度O(nlogn)
最坏时间复杂度:O(n2)
稳定性:不稳定

6. 归并排序

归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。
将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁最小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。
在这里插入图片描述
代码思路:
(1)初步代码设计:递归实现拆分!

def merge_sort(alist):
	n = len(alist)
	mid = n//2
	left_li = merge_sort(alist[:mid])
	right_li = merge_sort(alist[mid:])

(2)写递归一定注意写终止条件,避免死循环。这里不能无限拆分,拆到列表长度 为1时就不拆了!

def merge_sort(alist):
	n = len(alist)
	if n <= 1:
		return

	mid = n//2
	min = merge_sort(alist[:mid])

完整代码如下:
14_merge_sort.py代码:

def merge_sort(alist):
	"""归并排序"""
	n = len(alist)
	if n <= 1:
		return alist

	mid = n//2

	# 左部分列表: 采用归并排序后形成的有序的新的列表
	left_li = merge_sort(alist[:mid])# alist[:mid]表截取从开头到mid即下标0~mid的部分列表

	# 右部分: 采用归并排序后形成的有序的新的列表
	right_li = merge_sort(alist[mid:])# alist[mid:]表截取从mid到结尾即下标mid~len-1的部分列表

	# 将左右两个有序的子序列合并为一个新的整体
	left_pointer, right_pointer = 0, 0 # 指针,记录下标
	result = [] # 存放排序后的列表

	while left_pointer < len(left_li) and right_pointer < len(right_li):
		if left_li[left_pointer] <= right_li[right_pointer]:#等号保证了此算法(归并排序算法)的稳定-----见时间复杂度那里总结。若不加等号则变不稳定
			result.append(left_li[left_pointer])
			left_pointer += 1
		else:
			result.append(right_li[right_pointer])
			right_pointer += 1

	result += left_li[left_pointer:]
	result += right_li[right_pointer:]
	return result

#test
if __name__ == "__main__":
	li = [54, 23, 32, 324, 34, 324, 3]
	print(li)
#重点:
	merge_sort(li)#归并排序不改变原列表顺序,因为此法是新建一个result存放新的列表,从原列表alist往result里面放值
	print(li)
	print(merge_sort(li))

最优时间复杂度:O(nlogn) ------ 看上面开始的图,第一步(合1)需要执行n次,第二步(合2)需要执行n次
最坏时间复杂度:O(nlogn)
稳定性:稳定
只有归并排序算法需要开辟一块新的空间,虽然时间上它是好的效率高的,但是空间上它是大的。

排序算法总结对比

在这里插入图片描述

总结:

需要掌握3、4种排序算法不要求全部掌握。

但是!快排必须掌握,因为快排的时间复杂度最低效率最高(看最坏情况,见上表)应用是最广泛的!
虽然归并排序时间复杂度和快排一样好,但归并排序需要另开辟一额外的空间存放新列表占用空间大,所以快排是目前最优的排序算法!
虽然快排不稳定,但在实际应用中我们一般不需要保序(值相等的时候保持原次序),如果需要保序那就不用快排了。

7. 二分查找(折半查找)

联想实际查字典怎么查,让你查你的姓,你实际试试。比如“令狐”(Linghu),肯定是字典拿来中间随便翻开一页,如果你翻到的拼音在你的姓拼音之前比如你翻到了拼音H位置(你要找的令狐拼音开头L在H后),那么就再往后面随便一翻;如果你翻到的拼音在你的姓拼音之后比如你翻到了拼音O位置(你要找的令狐拼音开头L在O前),那么就再往前面随便一翻…如此下去,直到找到为止。
在实际的查找案例中,若找不到,则说明没有我们可以返回False了。
在这里插入图片描述

注意:

使用二分查找(折半查找)的前提:被查的列表是有序列表,即升序或降序,如1, 3, 4, 7, 43,344。或者3223, 233, 23, 29, 6, 2这样的

法1(递归法):

15_binary_search.py代码:

def binary_search(alist, item):
	"""二分查找(递归法)"""
	n = len(alist)
	if n > 0:
		mid = n//2# 一定记住双斜线除号得到整数,单斜线除号得到小数
		if alist[mid] == item:
			return True
		elif item < alist[mid]:
			return binary_search(alist[:mid], item)#这里一定记得写return
		else:
			return binary_search(alist[mid+1:], item)#这里一定记得写return
	return False


#test
if __name__ == "__main__":
	li = [54, 23, 32, 324, 34, 324, 3]
	print(binary_search(li, 23))#23在li列表中,结果True
	print(binary_search(li, 100))#100不在li列表中,结果False

"""
运行结果:
True
False
"""
法2(first、last法):
def binary_search_2(alist, item):
	"""二分查找(非递归法)"""
	n = len(alist)
	first = 0#起始。这个叫first、last法,或者叫start、end法
	last = n-1#末尾
	while first <= last:
		mid = (first+last)//2
		if alist[mid] == item:
			return True
		elif item < alist[mid]:
			last = mid-1
		else:
			first = mid+1
	return False

最优时间复杂度:O(1) ------ 如li = [54, 23, 32, 324, 34, 324, 3],查找54。因为54在首元素,则执行一次即找到。
最坏时间复杂度:O(logn) ------ 同上面讲的算法,二分查找即折半查找,每次分成两部分,执行一次,共分了logn次(2的多少次幂),即1*logn = logn

8. 堆排序

def buildMaxHeap(arr):
    import math
    for i in range(math.floor(len(arr)/2),-1,-1):
        heapify(arr,i)
def heapify(arr, i):
    left = 2*i+1
    right = 2*i+2
    largest = i
    if left < arrLen and arr[left] > arr[largest]:
        largest = left
    if right < arrLen and arr[right] > arr[largest]:
        largest = right
    if largest != i:
        swap(arr, i, largest)
        heapify(arr, largest)
def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]
def heapSort(arr):
    global arrLen
    arrLen = len(arr)
    buildMaxHeap(arr)
    for i in range(len(arr)-1,0,-1):
        swap(arr,0,i)
        arrLen -=1
        heapify(arr, 0)
    return arr

9. 计数排序

def countingSort(arr, maxValue):
    bucketLen = maxValue+1
    bucket = [0]*bucketLen
    sortedIndex =0
    arrLen = len(arr)
    for i in range(arrLen):
        if not bucket[arr[i]]:
            bucket[arr[i]]=0
        bucket[arr[i]]+=1
    for j in range(bucketLen):
        while bucket[j]>0:
            arr[sortedIndex] = j
            sortedIndex+=1
            bucket[j]-=1
    return arr

10. 基数排序

def radix(arr):
    digit = 0
    max_digit = 1
    max_value = max(arr)
    #找出列表中最大的位数
    while 10**max_digit < max_value:
        max_digit = max_digit + 1
    while digit < max_digit:
        temp = [[] for i in range(10)]
        for i in arr:
            #求出每一个元素的个、十、百位的值
            t = int((i/10**digit)%10)
            temp[t].append(i)
        coll = []
        for bucket in temp:
            for i in bucket:
                coll.append(i)
        arr = coll
        digit = digit + 1
    return arr
轻松玩转AI(从Python开始之Python3进阶) 九步:   从Python开始 [链接]  描述性统计和推论性统计 [链接]  使用 Pandas 及其它 Python库 [链接]  数据展示和可视化 [链接]  概率回归模型 [链接]  机器学习基础 [链接]  非结构化数据处理 [链接]  机器学习进阶 [链接]  深度学习——神经网络 [链接] 从Python开始 Python入门 [链接] Python进阶 [链接]... 阅读详情

相关推荐

AI人工智能学习路径图

都看了昨天的热搜没有?韩国首位AI女主播金柱夏诞生,瞧瞧,这就是科技的力量啊!用智能代替人工解放人力,相信在未来这一定是个大的发展趋势,这时候可能就有人想要进入这个行业了,那么今天,小编就来给大家分享下AI人工智能的学习路径,帮助大家去学习与理解。 第一阶段:前置python基础知识 知识点: 1)Python环境搭建和基本概念 计算机组成、Python简介、变量和注释、bug和debug工具、常见数据类型、字符串的输出 2)基础运算与条件判断 输入、类型转换、算数运算、赋值及复合赋值运算、

CZ-001的博客 1542

Python搜索算法

搜索算法是指在一个数据集中查找特定元素的过程。这个过程包括遍历整个数据集,直到找到目标元素或者确定目标元素不存在。在计算机科学中,搜索算法是解决许多问题的关键,例如在排序算法中查找元素、搜索图形、计算机视觉中查找物体等等。常用的搜索算法有线性搜索和二分搜索。

weixin_51705589的博客 697

AI大模型基础-排序算法

文章摘要: 本文系统介绍了三种基础排序算法。首先解释了排序算法的稳定性概念(相同元素相对位置不变),并列举了稳定与不稳定算法示例。然后详细讲解了冒泡排序(相邻元素两两比较交换)、选择排序(每轮选择最小元素交换)和插入排序(将无序元素插入有序部分)的原理、实现步骤和时间复杂度分析。其中冒泡排序为稳定算法,时间复杂度O(n²);选择排序不稳定,最优O(n);插入排序通过构建有序序列实现排序。三种算法均附有Python代码实现样例,适用于小规模数据排序场景。

erainm 258

基于Python的盲目搜索人工智能实验

一、 无信息搜索(盲目搜索) 1。人工智能实验盲目搜索 1。人工智能实验盲目搜索。

毕业作品网站 1162

python列表基本操作之排序

博主简介:原互联网大厂tencent员工,网安巨头Venustech员工,阿里云开发社区专家博主,微信公众号java基础笔记优质创作者,csdn优质创作博主,创业者,知识共享者,欢迎关注,点赞,收藏。 目录一、背景二、增加元素1、append()方法2、extend()方法三、增加元素1、insert()方法四、查找计数元素1、index()方法2、count()方法五、删除元素1、del命令2、pop()方法3、remove()方法六、分片赋值七、列表排序1、reverse()方法2、sort()方法.

jiankang66的博客 3万+

python 人工智能各个搜索算法

python 人工智能各个搜索算法 深度广度贪婪A*最小代价

人工智能-A*启发式搜索算法解决八数码问题 Python实现

八数码问题也称为九宫问题。在 3×3 的棋盘,摆有八个棋子,每个棋子上标有 1 至 8 的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格(以数字 0 来表示),与空 格相邻的棋子可以移到空格中。要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。该问题可用A*启发式搜索算法求解。

SCY164759920的博客 3万+

人工智能·最快的排序算法.csv

人工智能·最快的排序算法.csv

基数排序 | 主位优先 & 次位优先 | C语言

一、桶排序 二、基数排序

用途:中英文学习笔记,如有侵权,可评论留言,及时清理;学历:NUS计算机硕士;SYSU地球物理学士 654

深入解析CycloneDDS跨域通信中的XML配置文件优化策略

本文深入解析了CycloneDDS跨域通信中XML配置文件的优化策略,重点介绍了网络接口配置、多播设置、性能调优参数及复杂场景下的配置案例。通过实战技巧和调试方法,帮助开发者在SoC环境中实现高效稳定的跨域通信,提升系统性能。

soda5的博客 688

OpenCV学习笔记(25)基于MFC和OpenCV的摄像机定标与立体匹配测试程序(20140505更新)

最近整理了一下这两年一直在用的摄像机定标与立体匹配测试程序,将代码进行了重构,界面也做了调整,分享出来方便有需要的朋友使用。当然我的编程能力有限,程序可能还有各种bug,请大家多多包涵。相关问题欢迎留言或email联系讨论,谢谢! ==================================================================================源码

晨宇思远 5万+

chatgpt赋能Python-python5个数从小到大排序

Python是一种高级编程语言,它非常适合数据科学、机器学习和人工智能等领域。它是一种易于学习、使用、扩展和维护的编程语言。Python中有许多内置的工具和库,可以帮助我们轻松地完成各种任务,包括排序。在Python中,有多种方法可以排序,比如选择排序、冒泡排序、插入排序等,我们将使用其中的一种方法来完成本文的任务。本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。作为通用的Aigc大模型,只是展现它原本的实力。对于颠覆工作方式的。

虚幻私塾 1408

Infineon MOSFET开关损耗计算实战指南

本文是英飞凌MOSFET开关损耗计算的实战指南。针对MOSFET发热问题,文章深入剖析了开关损耗的产生机理,并基于Infineon数据手册的关键参数,手把手推导了开通与关断损耗的工程计算公式。同时,指南强调了栅极电阻、寄生参数等实际因素对损耗的影响,并提供了从理论计算到实测优化的完整路径,帮助工程师精准评估与优化电源设计。

weixin_29212867的博客 444

排序与查找算法全解析:原理、实现与优化

系统梳理常见排序与查找算法的原理、实现、性能分析、工程优化与AI场景应用,结合面试高频题型、实战案例、常见陷阱、工程实践与前沿发展,助力算法面试与大数据/AI工程落地。掌握主流排序与查找算法原理、实现与性能分析注重工程优化与AI/大数据场景下的应用面试与实战并重,关注常见陷阱与前沿发展持续学习新型排序/查找技术,关注未来趋势。

加入“Super Entity”,与全能开发团队共探AI智能体与数字人项目,开启前沿技术之旅。 687

静态时序分析(STA)_深入解析Data to Data Checks的零周期挑战

本文深入解析了静态时序分析(STA)中Data to Data Checks的核心概念与零周期挑战。重点探讨了当Setup要求值超过时钟周期时,工具如何调整发射沿,并导致Hold检查的发射与捕获沿“分裂”这一反直觉现象。文章通过案例详细解读了时序报告,并提供了通过调整约束或接受多周期保持两种策略来应对这一挑战,帮助工程师正确理解和处理此类复杂时序检查。

weixin_29204205的博客 351

【Python・统计学】(两)多因素方差分析(原理及代码)

自学笔记,分享给对统计学原理不太清楚但需要在论文中用到的小伙伴,欢迎大佬们补充或绕道。ps:本文不涉及公式讲解(文科生小白友好体质)~(部分定义等来源于知乎) 本文重点:多因素方差分析 【1.多因素方差分析简单原理】 【2.多因素方差分析步骤】 【3.多因素方差分析代码】

TUTO_TUTO的博客 4866

chatgpt赋能python:Python五个数排序

本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。作为通用的Aigc大模型,只是展现它原本的实力。对于颠覆工作方式的ChatGPT,应该选择拥抱而不是抗拒,未来属于“会用”AI的人。🧡AI职场汇报智能办公文案写作效率提升教程 🧡专注于AI+职场+办公方向。下图是课程的整体大纲下图是AI职场汇报智能办公文案写作效率提升教程中用到的ai工具。

laod112的博客 504

DFT实战:如何用Synopsys工具搞定多时钟域Scan Chain设计(附避坑指南)

本文详细解析了使用Synopsys DFT Compiler工具链实现多时钟域Scan Chain设计的全流程,包括时钟混合策略、跨时钟域平衡技巧和实战脚本剖析。通过量产验证的工程实践方案,帮助DFT工程师有效解决复杂SoC设计中的Scan Chain挑战,提升测试效率和质量。

mm9012的博客 1034

python3破冰人工智能pdf 微盘_Python 3破冰人工智能 从入门到实战

《Python 3破冰人工智能 从入门到实战》简介:内容简介:本书创新性地从数学建模竞赛入手,深入浅出地讲解了人工智能领域的相关知识。本书内容基于Python 3.6,从人工智能领域的数学出发,到Python在人工智能场景下的关键模块;从网络爬虫到数据存储,再到数据分析;从机器学习到深度学习,涉及自然语言处理、机器学习、深度学习、推荐系统和知识图谱等。 此外,本书还提供了近140个代码案例和大量图...

weixin_33646989的博客 1135

Android Framework SurfaceFlinger面试题及参考答案

请简述 SurfaceFlinger 在 Android 系统中的作用。 SurfaceFlinger 是 Android 系统中一个非常关键的服务。它主要负责将多个应用程序的 Surface 合成到一个屏幕显示内容中。 从应用程序的角度来看,每个应用都有自己的 UI 界面,这些 UI 界面实际上是由一系列的图层(Surface)构成。例如,一个应用可能有背景图层、按钮图层、文本图层等。应用通过向 SurfaceFlinger 提供这些 Surface 来请求显示。 SurfaceFl

大模型大数据攻城狮的专栏 1186

Winform从入门到精通(2)——Button(史上最全)

本文介绍winform中Button控件的详细用法,包括所有属性和事件

qq_34059233的博客 1万+

我用了 5 分钟,把蓝耘 MaaS 接进 Python,写了个命令行 AI 编程助手

蓝耘 MaaS(Model as a Service)是一个大模型服务平台,说白了就是把 DeepSeek、GLM、Qwen、Kimi 这些热门模型打包成标准的 API 服务。不用自己部署模型,不用管 GPU,注册之后拿到一个 API Key 就能直接调用。更重要的是,蓝耘 MaaS 的接口完全兼容 OpenAI 的 API 格式。这意味着所有你用过的 OpenAI SDK 调用代码,把base_url改一下就能直接跑,零学习成本。

Pocker_Spades_A的博客 1万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

十大排序——python实现

3.二分查找思想:二分查找通过比较数组中间的数据与目标数据的大小,可以得知目标数据是在数组的左边还是右边。重复执行该操作就可以找到目标数据,或得出目标数据不存在的结论。(1)二分查找必须建立在数据已经排好序的基础上才能使用,因此添加数据时必须加到合适的位置,这就需要额外耗费维护数组的时间。(2)线性查找时,数组中的数据可以是无序的,因此添加数据时也无须顾虑位置,直接把它加在末尾即可,不需要耗费时间。4.二分查找利用已排好序的数组,每一次查找都可以将查找范围减半。(1)查找的数量只能是一个,不能是多个;

2301_80038325的博客 1167

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

用Python 3实现快速排序和插入排序代码详解 !

今天用Python 3版本实现快速排序和插入排序。先对Python语言做个简单介绍。 Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年。Python 源代码同样遵循 GPL(GNU General Public License)协议。 Python的3.0版本,常被称为Pyth...

Pythoncxy的博客 255

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

python编程人工智能小例子,python人工智能100例子

大家好,小编为大家解答python用于人工智能的例子的问题。很多人还不知道python编程人工智能小例子,现在让我们一起来看看吧!作者 | 快学Python来源 | https://github.com/jackzhenguo/python-small-examples今天给大家分享一下60个Python小例子,拿来即用!

l463747243的博客 2120

python 快速排序_用Python 3实现快速排序和插入排序代码详解

今天用Python 3版本实现快速排序和插入排序。先对Python语言做个简单介绍。Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年。Python 源代码同样遵循 GPL(GNU General Public License)协议。Python的3.0版本,常被称为Pyt...

weixin_39625172的博客 212
上一篇: 人工智能3.4 -- python算法篇(四)栈和队列
下一篇: csdn博客markdown 如何输入上下标(如平方指数等)
Acegem
博客等级 码龄7年 190粉丝 96原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值