【数据结构和算法】【笔记】python数据结构——排序(1)冒泡排序

本文介绍了排序算法的基本概念,包括内部排序和外部排序,并详细讲解了冒泡排序的工作原理、时间复杂度和稳定性。冒泡排序是一种简单的排序算法,通过重复遍历并比较元素来实现排序。文章还提供了冒泡排序的Python实现,探讨了如何通过设置岗哨优化排序过程,以减少不必要的比较次数。
摘要由CSDN通过智能技术生成

1.排序简介

排序算法(Sorting algorithm)是一种能将一串数据依照特定顺序进行排列的一种算法。

分类:内部排序、外部排序(区别在于数据量大小,是否需要借助外部辅助存储器)。

常见的排序法有:冒泡排序、选择排序、插入排序、合并排序、快速排序、堆积排序、希尔排序、基数排序。

排序算法的分析

  • 稳定性:相同键值的记录在排序后仍然保持原来的次序。
  • 时间复杂度
  • 空间复杂度:排序法所用到的额外空间。

2. 冒泡排序

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

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

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

冒泡法分析

  •  时间复杂度:O(n^{2})
  •  稳定性:  稳定
  •  空间复杂度:只需一个额外的空间,空间复杂度为最佳。

冒泡排序实现:

思路:第一遍时  i从0到n-1, 两两比较,if当前大于后一个值,交换,最后一个即为最大值

           第二遍    i从 0 到n -2(即倒数第二个元素),执行同上步骤。

          因此令j 0 到n-2  ,i  为0到 n-1-j

         第一遍  j=0 , i range(0,n-1)   (即最后一个元素)

         第二遍  j=1 ,i range(0,n-2)   (即倒数第二个元素)

         第三遍 j= 2  i range(0,n-3)  (即倒数第二个元素)

                                        ……

         最后  i (0,1), 得 n-1-j=1  所以 j最大为n-2,故j range(n-1)

def bubble_sort(alist):
    """冒泡排序"""
    n = len(alist)
    for j in range(n-1):
        for i in range(0, n-1-j):
            # 班长从头走到尾
            if alist[i] > alist[i+1]:
                alist[i],alist[i+1] = alist[i+1], alist[i]

或者 

def bubble_sort(alist):
    for j in range(len(alist)-1,0,-1):
        # j表示每次遍历需要比较的次数,是逐渐减小的
        for i in range(j):
            if alist[i] > alist[i+1]:
                alist[i], alist[i+1] = alist[i+1], alist[i]

例1 使用冒泡排序对数列排序

data=[16,25,39,27,12,8,45,63]	# 原始数据 
print('冒泡排序法:原始数据为:')
for i in range(8):
    print('%3d' %data[i],end='')
print()

for i in range(7,-1,-1): #扫描次数
    for j in range(i):
        if data[j]>data[j+1]:#比较,交换的次数
            data[j],data[j+1]=data[j+1],data[j]#比较相邻的两数,如果第一个数较大则交换
    print('第 %d 次排序后的结果是:' %(8-i),end='') #把各次扫描后的结果打印出来
    for j in range(8):
        print('%3d' %data[j],end='')
    print()
	
print('排序后的结果为:')
for j in range(8):
    print('%3d' %data[j],end='')
print()

 

例2  发现冒泡排序的一个缺点,无论排序是否完成都固定实现n(n-1)次,因此使用岗哨的概念,可以提前中断程序

#[示范]:改进的冒泡排序法
def showdata(data):    #使用循环打印数据
    for i in range(6):
        print('%3d' %data[i],end='')
    print()
    
def bubble (data):
    for i in range(5,-1,-1):
        flag=0    #flag用来判断是否执行了交换操作
        for j in range(i):
            if data[j+1]<data[j]:
                data[j],data[j+1]=data[j+1],data[j]
                flag+=1  #如果执行过交换操作,则flag不为0
        if flag==0:
            break
        #当执行完一次扫描就判断是否执行过交换操作,如果没有交换过数据,
	    #表示此时数组已完成排序,故可直接跳出循环 
        print('第 %d 次排序:' %(6-i),end='')
        for j in range(6):
            print('%3d' %data[j],end='')
        print()
    print('排序后的结果为:',end='')
    showdata (data)

def main():
    data=[4,6,2,7,8,9]  #原始数据
    print('改进的冒泡排序法测试用的原始数据为:')
    bubble (data)
    
main()

使用flag, 当不执行交换时,说明已排好序,此时flag=0, 跳出循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值