排序算法
选择排序(Selection Sort)是一种简单直观的排序算法,它的基本思想是每次从待排序的数据元素中选择最小(或最大)的一个元素,放到已排序序列的末尾,直到全部元素排序完成。选择排序的时间复杂度为O(n^2),空间复杂度为O(1)
arr = [6, 2, 1, 3, 5, 7, 4, 8, 9]
for i in range(len(arr) - 1): # -1 少比较1轮
for j in range(i + 1, len(arr)):
if arr[i] > arr[j]:
arr[i], arr[j] = arr[j], arr[i] print(arr)
冒泡排序
冒泡排序(Bubble Sort)是一种基本的排序算法,它的基本思想是通过不断地比较相邻的元素,如果顺序不对则交换它们,直到没有任何需要交换的元素为止。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1)。
arr = [6, 2, 1, 3, 5, 7, 4, 8, 9]
for i in range(len(arr) - 1):# -1 少比较1轮
for j in range(len(arr) - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
print(arr)
插入排序
插入排序(Insertion Sort)是一种简单直观的排序算法,它的基本思想是将待排序的数据分成已排序和未排序两部分,每次从未排序部分取出一个元素插入到已排序部分的适当位置,直到全部元素排序完成。插入排序的时间复杂度为O(n^2),空间复杂度为O(1)。插入排序在数据量较小或基本有序的情况下表现较好
arr = [6, 2, 1, 3, 5, 7, 4, 8, 9]
'''''' for i in range(1, len(arr)):
j = i
while j > 0 and arr[j - 1] > arr[j]:
arr[j], arr[j - 1] = arr[j - 1], arr[j]
j -= 1 """
# 优化后的插入排序
for i in range(1, len(arr)):
e = arr[i]
j = i
while j > 0 and arr[j - 1] > e:
arr[j] = arr[j - 1]
j -= 1
arr[j] = e
print(arr)
希尔排序
-
希尔排序(Shell Sort):希尔排序是一种插入排序的改进算法,它的基本思想是将待排序的元素按照一定间隔分组,对每个分组进行插入排序,然后逐渐减小间隔直到间隔为1,最后进行一次插入排序。希尔排序的时间复杂度取决于间隔序列的选择,一般为O(n^1.3),空间复杂度为O(1)。
快速排序
-
快速排序(Quick Sort):快速排序是一种分治排序算法,它的基本思想是选择一个基准元素,将小于基准的元素放到基准的左边,大于基准的元素放到基准的右边,然后递归地对左右两部分进行排序。快速排序的平均时间复杂度为O(nlogn),最坏情况下为O(n^2),空间复杂度为O(logn)。
堆排序
-
堆排序(Heap Sort):堆排序是一种基于完全二叉树的排序算法,它的基本思想是将待排序的元素构建成一个最大堆或最小堆,然后依次将堆顶元素与最后一个元素交换并调整堆,直到所有元素排序完成。堆排序的时间复杂度为O(nlogn),空间复杂度为O(1)。
归并排序
-
归并排序(Merge Sort):归并排序是一种分治排序算法,它的基本思想是将待排序的元素不断地二分直到每个子序列只有一个元素,然后递归地将相邻的子序列合并并排序。归并排序的时间复杂度为O(nlogn),空间复杂度为O(n)。
计数排序
计数排序(Counting Sort)是一种非比较排序算法,它的基本思想是统计待排序元素中每个元素出现的次数,然后根据元素的值和出现次数将元素放回到正确的位置上,从而实现排序。计数排序要求待排序的元素必须是有确定范围的整数,并且不能有负数。计数排序的时间复杂度为O(n+k),其中n是待排序元素的个数,k是元素的范围大小。计数排序的空间复杂度也为O(n+k)。计数排序是一种稳定的排序算法,适用于待排序元素范围较小的情况下,效率较高。
arr = [8,2,1,4,8,7,9,2,3,4]
minValue = min(arr)
maxValue = max(arr)
temp = [0] * (maxValue - minValue + 1)
for i in range(len(arr)):
temp[arr[i] - minValue] += 1
k = 0
for index in range(len(temp)):
while temp[index] > 0:
arr[k] = index + minValue
k += 1
temp[index] -= 1
print(arr)
基数排序
-
基数排序(Radix Sort):基数排序是一种非比较排序算法,它的基本思想是将待排序的元素按照个位、十位、百位等位数进行排序,从低位到高位依次进行排序,直到所有位数排序完成。基数排序的时间复杂度为O(d*(n+k)),其中d是最大数字的位数,n是元素个数,k是数字范围大小。
桶排序
-
桶排序(Bucket Sort):桶排序是一种排序算法,它的基本思想是将待排序的元素分配到不同的桶中,然后对每个桶中的元素进行排序,最后将所有桶中的元素按照顺序合并起来。桶排序的时间复杂度为O(n+k),其中n是元素个数,k是桶的个数。
查找算法
二分查找:要求数据必须有序,只考虑位置
arr =[ 1,2,3,4,5,6,7,8,9]
minIndex = 0
maxIndex = len(arr) - 1
midIndex = (minIndex + maxIndex) // 2
key = 8
while arr[midIndex] !=key:
if arr[midIndex] <key:
minIndex = midIndex + 1
else:
maxIndex = midIndex - 1
if minIndex > maxIndex:
break
midIndex = (minIndex +maxIndex) // 2
print(midIndex)
插值查找:数据必须是有序的,除了要考虑位置还得考虑元素的分布情况
"""
插值查找适用于数据分布比较均匀的情况
low 区间最小值角标
high 区间最大值角标
mid 区间中间值角标
mid = (key- arr[low]) / (arr[high] - arr[low]) * (high - low) + low
""" arr = [1,12,24,31,32,36,42,45,51,52,65,72,99]
low = 0
high = len(arr) - 1
mid = 0
key = 31
while True:
mid = int((key - arr[low]) / (arr[high] - arr[low]) * (high - low)) + low
if mid > high or mid < low:
mid = -1
break
if arr[mid] == key:
break
elif arr[mid] < key:
low = mid + 1
else: high = mid - 1
print(mid)
斐波那契查找
列表对象函数
对象函数是区别于内置函数的,内置函数直接调用即可len() max()
对象函数 必须通过某一个具体的对象来调用 列表.函数名()
# append()
# 将某一个元素对象添加在列表的表尾
# 如果添加的是其他的序列,该序列也会被看成是一个数据对象
arr = [1,2,3,4]
arr.append(5)
print(arr)
arr2 = [6,7,8]
arr.append(arr2)
print(arr) # count()
# 统计列表当中 某一个元素出现的次数
arr = [1,2,3,4,1,2,3,1,1,2,0,0,1]
print(arr.count(1))
# extend()
# 在当前列表中 将传入的其他序列的元素添加在表尾
arr1 = [1,2,3]
arr2 = [4,5,6]
arr1.extend(arr2)
print(arr1)
"""
arr1.extend(7)
TypeError: 'int' object is not iterable(可迭代的=序列) """
arr1.extend("ABC")
print(arr1)
# index()
# 查找(从左到右)元素第一次出现的位置(角标)
arr = [1,2,3,4,5,6,7,4,5,6,9]
print(arr.index(4))
print(arr.index(4, 5, 8)) #[5, 8) 区间中找4的角标
"""
print(arr.index(10)) ValueError: 10 is not in list 找不到则报错
"""
# insert(index, obj)
# 在某一个角标出处插入一个元素
arr = [1,2,3,4]