Bootstrap

python数据结构———查找和排序1

查找

python中有内置函数index()来实现基本的查找功能,但是我们这里还是简单介绍一下两种基本的查找顺序查找二分查找来了解一下查找的基本原理。

顺序查找

def linear_search(li,val)#li传入参数列表名,val要查找的参数值
	for ind,v in enumerate(li):#利用for循环遍历列表的下标和值
		if v==val:#如果查找到相同的就返回下标值
			return ind
	else:
		return None#如果历遍完没有找到就返回None

顺序查找的时间复杂度为O(n)

二分查找

def binary_search(li,val):#二分查找只能用于有序列表的查询
	#li传入参数列表名,val要查找的参数值
	left=0
	right=len(li)-1
	while left<=right:#判断是否扫完列表
		mid=(left+right)//2#每次重新计算mid的值
		if li[mid]>val:
			right=mid-1#说明要查找的值在列表的左半边,缩小列表范围
		elif li[mid]<val:
			left=mid+1#说明要查找的值在列表的右半边,缩小列表范围
		else:
			return mid#列表中找到val的情况,直接返回下标
	return None

这里需要注意二分查找必须建立在有序表的基础上面,如果不是就不能用二分查找,二分查找的时间复杂度只有O(logn)。

python自带的查找函数

index对于字符串和列表可以使用该方法来进行查找指定值所在的下标值。

Li=[1,2,3,4,5,6,7,8,9]
Li.index(3)
#结果:2

find函数只能用于字符串中,查找字符串中的子字符串,并返回下标值。

str1="hahuhahei"
print(str1.find('hh'))#没有找到时返回-1
#结果:-1

count函数计算出现的次数

str1="hahuhahei"
str1.count('h')#对于字符串和列表都兼容
#结果:4

排序

在讲到排序,我们首先会讲到的几个排序都是原地排序,一般来说都是不再需要其他的空间内存,直接实现列表元素相互交换(通常要需要一个单位内存,可以忽略不计)这里我们理解好两个概念,已排序区和未排序区将对我们学习此类的排序有很大帮助。

冒泡排序

冒泡排序是一个常用的排序方法,其特点能检测到排序中的列表是否已完成好按要求的排序,从而能够节省很多时间,接来让我们一起来看看怎么实现的吧!

def bubble_sort(li):
	for i in range(len(li)-1):#只用循环n-1就是把前n-1个元素归位,第n个就自然再自己位置上了
	#第i趟的目的是把下标倒数第i个位置的元素安顿好
		flag=0
		for j in range(n-1-i):
			if li[j]>li[j+1]:#这里把数值大的元素往后排,是一个顺序列表排序
				li[j],li[j+1]=li[j+1],li[j]
				flag=1
		if flag==0:
			return

选择排序

其原理和冒泡排序差不多,我们要注意这里的已排序区域是在列表的首部,未排序区再列表的尾部。

def select_sort(li):
	for i in range(len(li)-1):#还是安排n-1趟就够了
		min_loc=i
		for j in range(i+1,len(li)):#j在下标为i+1到尾部的元素之间游走
			if li[j]<li[i]:
				min_loc=j#依次访问后面的变量一旦有小于的立即修改记录的下标值
		li[min_loc],li[i]=li[i],li[min_loc]	

插入排序

这个排序比较生动的一点就是它和打扑克摸牌是一样的在每摸一张牌,就要在有序区找到它该插入的位置,来实现排序。

def insert_sort(li)
	for i in range(1,len(li)):#可以表示摸到的第几张牌,真正的第一张不用排序,这里第二个算作第一张牌
		num=li[i]#记录一下大小,等会要占用它的位置
		for j in range(0,i,-1):#从后往前访问,方便挪位置#找到插入的位置
			if li[j]<num:
				break
			li[j+1]=li[j]#其实是如果不满足上面条件,那么就将j位置的数据往后移动一个位置
		li[j+1]=num	

快速排序

快速排序的原理其实是使用了一个递归的思想,将长列表划分为小列表进行排序,能够达到更快速的方式。

def partition(li,left,right):
	num=li[left]
	while left<right:
		while left<right and li[right]>=num:
			right-=1
		li[left]=li[right]
		while left<right and li[left]<=num:
			left+=1
		li[right]=li[left]
	li[left]=num
	return left
def quick_sort(li,left,right):
	if left<right:
		mid=partition(li,0,len(li)-1)#目标是每次找到第一个元素的位置
		quick_sort(li,0,mid-1)
		quick_sort(li,mid+1,len(li)-1)
;