设为首页 加入收藏

TOP

python实现各种算法详解,以及时间复杂度(一)
2023-07-23 13:43:03 】 浏览:41
Tags:python 时间复

python实现各种排序

image-20230406144037130

image-20230406144222498

1. 快速排序

1:首先取序列第一个元素为基准元素pivot=R[low]。i=low,j=high。

2:从后向前扫描,找小于等于pivot的数,如果找到,R[i]与R[j]交换,i++。

3:从前往后扫描,找大于pivot的数,如果找到,R[i]与R[j]交换,j--。

4:重复2~3,直到i=j,返回该位置mid=i,该位置正好为pivot元素。 完成一趟排序后,以mid为界,将序列分为两部分,左序列都比pivot小,有序列都比pivot大,然后再分别对这两个子序列进行快速排序。

以序列(30,24,5,58,16,36,12,42,39)为例,进行演示:

1、初始化,i=low,j=high,pivot=R[low]=30:

i j
30 24 5 58 16 26 12 41 39

2、从后往前找小于等于pivot的数,找到R[j]=12

i j
30 24 5 58 16 26 12 41 39
  • R[i]与R[j]交换,i++
i j
12 24 5 58 16 26 30 41 39

3、从前往后找大于pivot的数,找到R[i]=58

i j
12 24 5 58 16 26 30 41 39
  • R[i]与R[j]交换,j--
i j
12 24 5 30 16 26 58 41 39

4、从后往前找小于等于pivot的数,找到R[j]=16

i j
12 24 5 30 16 26 58 41 39
  • R[i]与R[j]交换,i++
i,j
12 24 5 16 30 26 58 41 39

5、从前往后找大于pivot的数,这时i=j,第一轮排序结束,返回i的位置,mid=i

Low mid-1 mid mid+1 High
12 24 5 16 30 26 58 41 3

此时已mid为界,将原序列一分为二,左子序列为(12,24,5,18)元素都比pivot小,右子序列为(36,58,42,39)元素都比pivot大。然后在分别对两个子序列进行快速排序,最后即可得到排序后的结果。

def quicksort(low,high,li):
    if low >= high:
        return li
    i = low
    j= high
    pivot = li[low]
    while i<j:
        while i<j and li[j]>pivot:
            j -= 1
        li[i] = li[j]
        while i<j and li[i]<pivot:
            i += 1
        li[j] = li[i]

    li[j] = pivot
    quicksort(low,i-1,li)
    quicksort(i+1,high,li)
    return li



lists=[30,24,5,58,18,36,12,42,39]
print("排序前的序列为:")
for i in lists:
    print(i,end =" ")
print("\n排序后的序列为:")
for i in quicksort(0,len(lists)-1,lists):
    print(i,end=" ")

2. 冒泡排序

冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

冒泡排序算法的运作如下:

  • 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  • 针对所有的元素重复以上的步骤,除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

image-20230405225515789

def bubblesort(li):
    for i in range(len(li)-1,0,-1):
        for j in range(1,i):
            if li[j-1]>li[j]:
                li[j-1],li[j] = li[j],li[j-1]

    return li

li = [54,26,93,17,77,31,44,55,20]
print(bubblesort(li))

3. 插入排序

插入排序(Insertion Sort)是一种简单直观的排序算法。它的工作原理是:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置后;
  6. 重复步骤2~5。

image-20230405230129654

这个算法和冒泡排序有点类似,都是两层for循环,一个是从正面挨个比,一个是倒着比

def insertsort(li):
    for i in range(1,len(li)):
        for j in range(i,0,-1):
            if li[j-1]>li[j]:
                li[j-1],li[j] = li[j],li[j-1]

    return li

li = [54,26,93,17,77,31,44,55,20]
print(insertsort(li))

4. 希尔排序

希尔排序是先取一个小于待排序列表长度的正整数d1,把所有距离为d1的数据看成一组,在组内进行插入排序。然后取一个小于d1的正整数d2,继续用d2分组和进行组内插入排序。每次取的分组距离越来越小,组内的数据越来越多,直到di=1,所有数据被分成一组,再进行插入排序,则列表排序完成。

希尔排序是基于插入排序进行优化的排序算法。在插入排序中,如果数据几乎已经排好序时,效率是很高的(想一下抓牌和插牌),时间复杂度为 O(n) 。但数据的初始状态并不一定是“几乎已经排好序”的,用插入排序每步只能将待插入数据往前移动一位,而希尔排序将数据分组后,每次可以往前移动di位,在di>1时进行的分组和组内排序可以将数据变成“几乎排好序”的状态,此时再进行最后一次插入排序,提高效率。

希尔排序的原理如下:

  1. 选择小于待排序列表长度 n 的正整数序列 d1,d2,...,di,其中 n>d1, d(i-1)>di, di=1 ,作为数据的间隔距离对列表进行分组。这里对 di 的取值和个数没有要求,只要是整数,d1<n,依次变小即可。

  2. 依次用 d1, ..., di 作为数据的距离对列表进行分组和组内插入排序,一共需要进行 i 轮排序。

  3. 在最后一轮排序前,列表中的数据达到了“几乎排好序”的状态,此时进行最后一轮插入排序。

以列表 [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21] 进

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇selenium 小技巧集合(一) 下一篇Django笔记十八之save函数的继承..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目