1 冒泡排序 (Bubble Sort)
- 冒泡排序对列表进行多次遍历。
- I它比较相邻的项目,并交换那些无序的项目。
- 每次遍历列表都将下一个最大的值放在合适的位置。
- 从本质上说,每件物品都是“气泡”上升到它所属的位置。
1.1气泡排序算法分析
- 无论项目在初始列表中如何排列。
- 使用冒泡排序方法对条目进行排序所需的步骤至少为n−1 * n−1步。
- 因此,该算法的性能为O(𝑛^2)。
bubble sort
1.2 Python 代码
def bubbleSort(alist):
for passnum in range(len(alist)-1,0,-1):
for i in range(passnum):
if alist[i]>alist[i+1]:
temp = alist[i]
alist[i] = alist[i+1]
alist[i+1] = temp
alist = [54,26,93,17,77,31,44,55,20]
bubbleSort(alist)
print(alist)
2. 选择排序(Selection Sort)
- 选择排序对列表的每一次遍历只进行一次交换。
- 选择排序在传递时查找最大的值,然后将其放在适当的位置。
- 对于冒泡排序,交换是在需要的时候进行的。
- 在第一次传递之后,最大的项目在正确的位置。
- 在第二次传递之后,第二大传递已经到位。
- 这个过程继续,需要n – 1次传递来排序n个项,因为最后一个项必须在(n – 1)次传递之后。
2.1 算法分析
- 实际上,该选择排序算法在理论上的计算机性能为O(𝑛^2)。
- 因为,最坏的情况下完成排序大约需要(n-1) * (n-1)个操作单位时间。
- 然而,在交换过程中,选择排序的计算<冒泡排序
selection sort
2.2 Python 代码
def selectionSort(alist):
for i in range(len(alist)-1):
left = i
for right in range(i+1,len(alist)):
if(alist[left]>alist[right]):
left = right
temp = alist[i]
alist[i] = alist[left]
alist[left] = temp
alist = [54,26,93,17,77,31,44,55,20]
selectionSort(alist)
print(alist)
3 插入排序(Insertion Sort)
- 插入排序的复杂度是O(𝑛^2),类似于选择排序和冒泡排序。
- 然而,它的工作方式与这两者略有不同。
- 它总是在列表的较低位置维护一个已排序的子列表。
- 然后将每个新项“插入”回前一个子列表,以便排序的子列表比前一个子列表大一项。
3.1 算法分析
- 因此,该算法的性能为O(𝑛^2)。
insertion sort
3.2 Python 代码
def insertionSort(alist):
for index in range(1,len(alist)):
currentvalue = alist[index]
position = index
while position>0 and alist[position-1]>currentvalue:
alist[position]=alist[position-1]
position = position-1
alist[position]=currentvalue
alist = [54,26,93,17,77,31,44,55,20]
insertionSort(alist)
print(alist)
4 希尔排序(Shell Sort)
- 壳层排序,有时被称为“递减递增排序”,
- 它改进了插入排序,将原始列表分解为许多更小的子列表,每个子列表都使用插入排序进行排序。
- 这种分割这些子列表的独特方法是shell排序的关键。
- shell排序使用增量i(有时称为gap),通过选择所有分隔i项的项来创建子列表。
4.1 Analysis of Algorithm
- 因此,该算法的性能为O(𝑛^2)。
shell sort
4.2 Python 代码
def gapInsertionSort(alist,start,gap):
for i in range(start+gap,len(alist),gap):
currentvalue = alist[i]
position = i
while position>=gap and alist[position-gap]>currentvalue:
alist[position]=alist[position-gap]
position = position-gap
alist[position]=currentvalue
def shellSort(alist):
sublistcount = len(alist)//2
while sublistcount > 0:
for startposition in range(sublistcount):
gapInsertionSort(alist,startposition,sublistcount)
print("After increments of size",sublistcount,
"The list is",alist)
sublistcount = sublistcount // 2
alist = [54,26,93,17,77,31,44,55,20]
shellSort(alist)
print(alist)
5 归并排序(Merge Sort)
- 归并排序是一种递归算法,它不断地将列表分成两半。
- 如果列表为空或只有一项,则按定义(基本情况)对其排序。
- 如果列表有多个项,则拆分列表并递归地对两部分调用归并排序。
- 一旦两半排序完成,就执行称为归并的基本操作。
- 归并是将两个较小的排序列表组合成一个单独的、排序的新列表的过程。
5.1 Analysis of Algorithm
- 归并排序的时间复杂度在所有三种情况下(最差、平均和最佳)都是O(n log n),因为归并排序总是将数组分成两半,并且合并这两半需要线性时间。
- 归并排序的空间复杂度为O(n)。
- 因此,该算法的性能为O(𝑛log𝑛)
merge sort
5.2 Python code
def mergeSort(alist):
print("Splitting ",alist)
if len(alist)>1:
mid = len(alist)//2
lefthalf = alist[:mid]
righthalf = alist[mid:]
mergeSort(lefthalf)
mergeSort(righthalf)
i=0
j=0
k=0
while i < len(lefthalf) and j < len(righthalf):
if lefthalf[i] <= righthalf[j]:
alist[k] = lefthalf[i]
i = i + 1
else:
alist[k] = righthalf[j]
j = j + 1
k = k + 1
while i < len(lefthalf):
alist[k] = lefthalf[i]
i = i + 1
k = k + 1
while j < len(righthalf):
alist[k] = righthalf[j]
j = j + 1
k = k + 1
print("Merging ", alist)
alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
mergeSort(alist)
print(alist)
6 快速排序(Quick Sort
- 快速排序首先选择一个值,称为主值。
- 尽管选择主元值有许多不同的方法,但我们将简单地使用列表中的第一项。
- 主值的作用是帮助分割列表。
- 主元值在最终排序列表中的实际位置(通常称为分割点)将用于对列表进行后续快速排序调用的分割
6.1 算法分析
- 该算法的最佳情况和平均情况是n log n。
- 然而,该算法在最坏情况下的性能为O(𝑛^2)
quick sort
6.2 python code
def quickSort(alist):
quickSortHelper(alist,0,len(alist)-1)
def quickSortHelper(alist,first,last):
if first<last:
splitpoint = partition(alist,first,last)
quickSortHelper(alist,first,splitpoint-1)
quickSortHelper(alist,splitpoint+1,last)
def partition(alist,first,last):
pivotvalue = alist[first]
leftmark = first+1
rightmark = last
done = False
while not done:
while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
leftmark = leftmark + 1
while alist[rightmark] >= pivotvalue and rightmark >= leftmark:
rightmark = rightmark -1
if rightmark < leftmark:
done = True
else:
temp = alist[leftmark]
alist[leftmark] = alist[rightmark]
alist[rightmark] = temp
# after the first loop end
temp = alist[first]
alist[first] = alist[rightmark]
alist[rightmark] = temp
return rightmark
alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
quickSort(alist)
print(alist)