目录
一、希尔排序(Shell Sort)
1、定义:是插入排序的一种,只不过间隔设为gap。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
2、原理:将数组列在一个表中并对列分别进行插入排序,重复这过程,不过每次用更长的列(步长更长了,列数更少了)来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身还是使用数组进行排序。
3、希尔排序的实现:
shell_sort(alist):
"""希尔排序法"""
n = len(alist)
# 初始步长
gap = n // 2 #折半设定,若n=9,则gap=4
while gap > 0: #gap=1进行最后一次循环
# 按步长进行插入排序
for j in range(gap, n):#从gap开始,控制子序列中的所有元素
i = j
# 插入排序
while i > 0:
if alist[i] < alist[i-gap]:
alist[i-gap], alist[i] = alist[i], alist[i-gap] #gap为步长
i -= gap
else:
break
gap = gap // 2 # 得到新的步长
alist = [54,26,93,17,77,31,44,55,20]
print(alist)
shell_sort(alist)
print(alist)
输出:
[54, 26, 93, 17, 77, 31, 44, 55, 20]
[17, 20, 26, 31, 44, 54, 55, 77, 93]
4、时间复杂度:
- 最优时间复杂度:根据步长序列的不同而不同
- 最坏时间复杂度:O(n2)
- 稳定想:不稳定
二、快速排序(Quicksort)
1、定义:快速排序,又称划分交换排序(partition-exchange sort),通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
2、工作步骤:
(1)从数列中挑出一个元素,称为"基准"(pivot),
(2)重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
(3)递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
3、快速排列的实现:
def quick_sort(alist, start, end):
"""快速排序"""
if start >= end: #递归的退出条件
return
Mid_value = alist[start]
low = start
high = end
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
#Mid_value两边分别快速排序,不断递归
quick_sort(alist, start, low-1)
quick_sort(alist, low+1, end)
alist = [54,26,93,17,77,31,44,55,20]
print(alist)
quick_sort(alist, 0, len(alist)-1)
print(alist)
输出:
[54, 26, 93, 17, 77, 31, 44, 55, 20]
[17, 20, 26, 31, 44, 54, 55, 77, 93]
4、时间复杂度
- 最优时间复杂度:O(nlogn)
- 最坏时间复杂度:O(n2)
- 稳定性:不稳定
三、归并排序
1、定义:归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。
2、归并排序的实现:
def merge_sort(alist):
"""归并排序"""
n = len(alist)
if n <= 1:
return alist
mid = n//2
#left采用归并排序后形成的有序的新的列表
left_li = merge_sort(alist[:mid])
#right采用归并排序后形成的有序的新的列表
right_li = merge_sort(alist[mid:])
#将两个有序的子序列合并成一个整体merge(left,right)
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
alist = [54,26,93,17,77,31,44,55,20]
print(alist)
sorted_li = merge_sort(alist)
print(alist)
print(sorted_li)
输出:
[54, 26, 93, 17, 77, 31, 44, 55, 20]
[54, 26, 93, 17, 77, 31, 44, 55, 20]
[17, 20, 26, 31, 44, 54, 55, 77, 93]
3、递归工作过程:
4、时间复杂度:
- 最优时间复杂度:O(nlogn)
- 最坏时间复杂度:O(nlogn)
- 稳定性:稳定
四、排序算法效率比较
多运用快速排序。
五、搜索
搜索的几种常见方法:顺序查找、二分法查找、二叉树查找、哈希查找
六、二分法查找
1、定义:二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
2、原理:首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
3、二分查找的实现:
(1)递归法实现
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)
else:
return binary_search(alist[mid+1:], item)
return False
testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,]
print(binary_search(testlist, 3))
print(binary_search(testlist, 13))
输出:
False
True
(2)非递归法实现
def binary_search(alist, item):
"""二分查找非递归版"""
n = len(alist)
first = 0
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
testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,]
print(binary_search(testlist, 3))
print(binary_search(testlist, 13))
输出:
False
True
4、时间复杂度:
- 最优时间复杂度:O(1)
- 最坏时间复杂度:O(logn)
来源:CSDN
作者:yanyx1
链接:https://blog.csdn.net/weixin_46309026/article/details/104821864