排序算法(python)

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)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值