常用的排序和查询,以下用python实现
冒泡排序
原理:临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,这样一趟过去后,最大或最小的数字被交换到了最后一位,然后再从头开始进行两两比较交换,直到倒数第二位时结束.
时间复杂度o(n*n)
def bubble(l):
flag = True
for i in range(len(l)-1, 0, -1):
if flag:
flag = False
for j in range(i):
if l[j] < l[j + 1]:
l[j], l[j+1] = l[j+1], l[j]
flag = True
else:
break
print(l)
li = [21,44,2,45,33,4,3,67]
bubble(li)
选择排序
原理:从所有序列中先找到最小的,然后放到第一个位置;之后再看剩余元素中最小的,放到第二个位置……以此类推,直到完成整个的排序工作
时间复杂度o(n*n)
def selection_sort(list2):
for i in range(0, len(list2)):
min = i
for j in range(i + 1, len(list2)):
if list2[j] < list2[min]:
min = j
list2[i], list2[min] = list2[min], list2[i]
li = [21,44,2,45,33,4,3,67]
selection_sort(li)
print(li)
插入排序
原理:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应的位置并插入。
时间复杂度o(n*n)
def insertion_sort(list2):
for i in range(1, len(list2)):
save = list2[i]
j = i
while j > 0 and list2[j - 1] > save:
list2[j] = list2[j - 1]
j -= 1
list2[j] = save
li = [21,44,2,45,33,4,3,67]
insertion_sort(li)
print(li)
#或者如下for循环:
def insertion_sort(list2):
for i in range(1, len(list2)):
save = list2[i]
index = i
for j in range(i,0,-1):
if list2[j-1] > save:
list2[j] = list2[j-1]
#等这次循环结束之后,把index带出来
index = j-1
else:
break
#避免每次都是循环到j=0才结束
list2[index] = save
li = [21,44,2,45,33,4,3,67]
insertion_sort(li)
print(li)
#对比发现while更容易理解,而且for循环是有问题的,因为第二个for循环中,每次都需要比较到index=0才结束,其实没必要这样,因为i之前的数据肯定是有序的,如果list2[j-1]<save,那么list2[j-1]之前的数据肯定也小于save;已经作了修正
#为什么不提倡用for,因为for是针对那种(0,len)的比较有优势,而插入排序的比较,不一定要到0
快速排序
快速排序采用的思想是分治思想。
快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。
递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。
时间复杂度: 平均o(nlogn), 最差o(n*n)
#把基准放到该放的位置
def sub_sort(array,low,high):
key = array[low]
while low < high:
while low < high and array[high] >= key:
high -= 1
array[low] = array[high]
while low <high and array[low] <= key: #这里可以去掉等号
low += 1
array[high] = array[low]
array[low] = key
return low
def quick_sort(array,low,high):
if low < high:
key_index = sub_sort(array,low,high)
quick_sort(array,low,key_index)
quick_sort(array,key_index+1,high)
if __name__ == '__main__':
array = [8,10,9,6,4,16,5,13,26,18,2,45,34,23,1,7,3]
print(array)
quick_sort(array,0,len(array)-1)
print(array)
顺序查找
原理:顺序查找的原理很简单,就是遍历整个列表,逐个进行记录的关键字与给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录。如果直到最后一个记录,其关键字和给定值比较都不等时,则表中没有所查的记录,查找失败。
时间复杂度:O(n);
def SequenceSearch(array,t):
len1 = len(array)
for i in range(0, len1):
if array[i] == t:
print('the location of ',t,' is: ',i)
return array[i]
return -1
if __name__ == "__main__":
a = [1,2,3,34,56,57,78,87]
b = 57
SequenceSearch(a, b)
二分法查找
二分法查找其实就是折半查找,一种效率较高的查找方法。针对有需数组来查找的。
主要思想是:(设查找的数组期间为array[low, high])
(1)确定该期间的中间位置K
(2)将查找的值T与array[k]比较。若相等,查找成功返回此位置;否则确定新的查找区域,继续二分查找。区域确定如下:
a.array[k]>T 由数组的有序性可知array[k,k+1,……,high]>T;故新的区间为array[low,……,K-1]
b.array[k]<T 类似上面查找区间为array[k+1,……,high]。每一次查找与中间值比较,可以确定是否查找成功,不成功当前查找区间缩小一半。递归找,即可。
时间复杂度:O(log2n);
def BinarySearch(array,t):
low = 0
height = len(array)-1
while low < height:
mid = int((low+height)/2)
if array[mid] < t:
low = mid + 1
elif array[mid] > t:
height = mid - 1
else:
print('the location of ',t,' is: ',mid)
return array[mid]
return -1
if __name__ == "__main__":
a = [1,2,3,34,56,57,78,87]
b = 57