基于python的冒泡算法、鸡尾酒算法、快速排序算法、程序设计(持续更新)

冒泡算法

冒泡算法就是通过相邻两个数依次做比较,取大/取小进行位置调换,最后进行排序。
对冒泡算法进行了优化,在第二层循环处添加了type判断了后续是否已经进行好排序,如果已经排好序则跳出循环。
若对存在大量已经有序数列进行排序添加了sort_lastnumber记录了有序数列的位置,对后面的数不再遍历

程序片段

def bubble(sort_number,sort_type):                           #冒泡排序法 sort_type=1为倒序 0为正序
    print('冒泡排序:', len(sort_number))
    global sort_lastnumber                                   #末端排序标志位
    global sort_last_len                                     #排序数列长度
    sort_lastnumber = 0
    sort_last_len = len(sort_number)-1
    print(sort_last_len)
    for i in range(0,len(sort_number)):
        print(i)
        type = True
        for j in range(0,sort_last_len):
            #print('j:',j)
            if (sort_number[j+1]<sort_number[j] and sort_type == 0) or (sort_number[j+1]>number[j] and sort_type == 1):
                item = sort_number[j+1]
                sort_number[j+1]=sort_number[j]
                sort_number[j]=item
                type = False
                sort_lastnumber = j
                print('冒泡排序:',sort_number)
                draw1(sort_number, sort_number[j])
        sort_last_len =sort_lastnumber
        if type == True:
            return

效果视频

冒泡排序

鸡尾酒算法

鸡尾酒算法就是先是从左到右,再从右到左排序,来来回回进行排序。与冒泡算法有相似处。

程序片段

def Cocktail_sort(sort_number,sort_type):
    print('鸡尾酒排序:',sort_number)
    for i in range(0,(len(sort_number)-1)//2):
        type = True
        print('外层:',i)
        for j in range(0,len(sort_number)-1):
            if(sort_number[j+1]>sort_number[j] and sort_type ==1) or (sort_number[j+1]<sort_number[j] and sort_type ==0):
                item = sort_number[j+1]
                sort_number[j+1]=sort_number[j]
                sort_number[j]=item
                type=False
                print('鸡尾酒排序:', sort_number)
                draw1(sort_number, sort_number[j])
        if type == True:
                break
        type = True
        for k in range(len(sort_number)-2,0,-1):
            if(sort_number[k-1]<sort_number[k] and sort_type ==1)or (sort_number[k-1]>sort_number[k] and sort_type ==0):
                item=sort_number[k]
                sort_number[k]=sort_number[k-1]
                sort_number[k-1]=item
                type=False
                print('鸡尾酒排序:', sort_number)
                draw1(sort_number, sort_number[k])
        if type == True:
                break

视频效果

基于python—鸡尾酒排序

快速排序算法

所谓快速排序算法,就是确定一个基数,以基数进行对比,将数分为大于基数和小于基数的两端,将基数-1和基数+1分别为下次递归的左终点,和右起始点,进行递归,最终达到有序数列。具体分布算法有双边循环、和单边循环。

快速排序算法(双边循环)

快速排序算法(双边循环)首先通过确定一个基准数,列表两端分别为start和end,定义两个指针(不是实际的指针,标志位),分别位left和right,指向左端和有端,从右到左开始与基准数做比较,如果大于/小于(区别是排序的正/倒序)基准数,则换left从左到右进行与基准数做比较,如果小于/大于基准数,这停止继续比较,把left和right的数进行对调,然后再次进行和基准数进行比较,直到left和right重合(下文记为left),将基准数与其对调。后以重合部分的两端继续做上面部分,一个是以[start,left-1],一个是以[left+1,end],继续重复上述快速排序方法,可以采用递归的方法,进行快速排序。

def Quick_sort(sort_number,left_pointer,right_pointer,sort_type,loop_type):                  # 快速排序法
    global location_point

    if(left_pointer >= right_pointer):
        return
    if(loop_type == 0):
        print("双边循环")
        location_point = Bilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
        Quick_sort(sort_number,left_pointer,location_point-1,sort_type,loop_type)
        Quick_sort(sort_number,location_point+1,right_pointer,sort_type,loop_type)
    elif(loop_type == 1):
        print("单边循环")
        location_point = Unilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
        print("第一个:")
        Quick_sort(sort_number, left_pointer, location_point - 1, sort_type, loop_type)
        print("第二个:")
        Quick_sort(sort_number, location_point + 1, right_pointer, sort_type, loop_type)

def Bilateral_loop(sort_number,start_pointer,end_pointer,sort_type):                                     #双边循环法
    global pivot
    global left
    global right
    pivot = sort_number[start_pointer]
    print('基准:',pivot)
    left = start_pointer
    right = end_pointer
    while(left != right):
        print(sort_type)
        while((left<right and sort_number[right]>pivot and sort_type == 0) or
              (left<right and sort_number[right]<pivot and sort_type == 1)):
            right-=1
        while((left<right and sort_number[left]<=pivot and sort_type == 0) or
              (left<right and sort_number[left]>=pivot and sort_type == 1)):
            left+=1
        if(left<right):
            item = sort_number[left]
            sort_number[left] = sort_number[right]
            sort_number[right] = item
            print('快速排序(双边循环):',sort_number)
            draw1(sort_number, sort_number[left])
    sort_number[start_pointer] = sort_number[left]
    sort_number[left] = pivot
    print('快速排序(双边循环):', sort_number)
    draw1(sort_number, sort_number[left])

    return left

快速排序(单边循环)

单边循环具体算法,首先确定一个基数和mark点指向基数,然后通过循环,如果发现比基数小/大的数,则将mark+1,并将此时mark点指向的数与比较的数进行对调。之后继续执行比较,如若发现比基数小/大的数,继续执行上述操作,当完成第一轮比较,可以将大于/小于基数的数分布到两端,将此时的mark-1和mark+1的点作为左端的终点和右端的起始点,通过递归的方式,再进行上述操作,最后会得出一个有序数列。

def Quick_sort(sort_number,left_pointer,right_pointer,sort_type,loop_type):                  # 快速排序法
    global location_point

    if(left_pointer >= right_pointer):
        return
    if(loop_type == 0):
        print("双边循环")
        location_point = Bilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
        Quick_sort(sort_number,left_pointer,location_point-1,sort_type,loop_type)
        Quick_sort(sort_number,location_point+1,right_pointer,sort_type,loop_type)
    elif(loop_type == 1):
        print("单边循环")
        location_point = Unilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
        print("第一个:")
        Quick_sort(sort_number, left_pointer, location_point - 1, sort_type, loop_type)
        print("第二个:")
        Quick_sort(sort_number, location_point + 1, right_pointer, sort_type, loop_type)
        
def Unilateral_loop(sort_number,start_pointer,end_pointer,sort_type):
    if(start_pointer >= end_pointer):
        return
    pivot = sort_number[start_pointer]
    mark = start_pointer
    print('快速排序(单边循环)0:', sort_number)
    #print('基准:', pivot,'mark:',mark)
    for i in range(start_pointer+1,end_pointer+1):
        print("i:",i)
        if(sort_number[i]<pivot and sort_type == 0) or\
          (sort_number[i]>pivot and sort_type == 1):
            mark+=1
            print("对调:",sort_number[mark],"和",sort_number[i])
            p = sort_number[mark]
            sort_number[mark] = sort_number[i]
            sort_number[i] = p
            draw1(sort_number,sort_number[mark])
            print('sort_number:', sort_number[i], '基准:', pivot, 'mark:', mark)
            print('快速排序(单边循环)1:', sort_number)
    sort_number[start_pointer] = sort_number[mark]
    sort_number[mark] = pivot
    draw1(sort_number, sort_number[mark])
    print('快速排序(单边循环)2:', sort_number)
    print('基准:', pivot, 'mark:', mark)
    #print('快速排序(单边循环):', sort_number)
    return mark

完整程序代码

import matplotlib.pyplot as plt
import numpy as np
number = np.array([4,7,3,5,6,2,8,1])


def bubble(sort_number, sort_type):                          # 冒泡排序法 sort_type=1为倒序 0为正序
    print('冒泡排序:', len(sort_number))
    global sort_lastnumber                                   # 末端排序标志位
    global sort_last_len                                     # 排序数列长度
    sort_lastnumber = 0
    sort_last_len = len(sort_number)-1
    print(sort_last_len)
    for i in range(0,len(sort_number)):
        print(i)
        type = True
        for j in range(0,sort_last_len):
            # print('j:',j)
            if (sort_number[j+1]<sort_number[j] and sort_type == 0) or (sort_number[j+1]>number[j] and sort_type == 1):
                item = sort_number[j+1]
                sort_number[j+1]=sort_number[j]
                sort_number[j]=item
                type = False
                sort_lastnumber = j
                print('冒泡排序:',sort_number)
                draw1(sort_number, sort_number[j])
        sort_last_len =sort_lastnumber
        if type == True:
            return

def Cocktail_sort(sort_number,sort_type):                   # 鸡尾酒排序法
    print('鸡尾酒排序:',sort_number)
    for i in range(0,(len(sort_number)-1)//2):
        type = True
        print('外层:',i)
        for j in range(0,len(sort_number)-1):
            if(sort_number[j+1]>sort_number[j] and sort_type ==1) or (sort_number[j+1]<sort_number[j] and sort_type ==0):
                item = sort_number[j+1]
                sort_number[j+1]=sort_number[j]
                sort_number[j]=item
                type=False
                print('鸡尾酒排序:', sort_number)
                draw1(sort_number, sort_number[j])
        if type == True:
                break
        type = True
        for k in range(len(sort_number)-2,0,-1):
            if(sort_number[k-1]<sort_number[k] and sort_type ==1)or (sort_number[k-1]>sort_number[k] and sort_type ==0):
                item=sort_number[k]
                sort_number[k]=sort_number[k-1]
                sort_number[k-1]=item
                type=False
                print('鸡尾酒排序:', sort_number)
                draw1(sort_number, sort_number[k])
        if type == True:
                break

def Quick_sort(sort_number,left_pointer,right_pointer,sort_type,loop_type):                  # 快速排序法
    global location_point

    if(left_pointer >= right_pointer):
        return
    if(loop_type == 0):
        print("双边循环")
        location_point = Bilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
        Quick_sort(sort_number,left_pointer,location_point-1,sort_type,loop_type)
        Quick_sort(sort_number,location_point+1,right_pointer,sort_type,loop_type)
    elif(loop_type == 1):
        print("单边循环")
        location_point = Unilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
        print("第一个:")
        Quick_sort(sort_number, left_pointer, location_point - 1, sort_type, loop_type)
        print("第二个:")
        Quick_sort(sort_number, location_point + 1, right_pointer, sort_type, loop_type)

def Bilateral_loop(sort_number,start_pointer,end_pointer,sort_type):                                     # 双边循环法
    global pivot
    global left
    global right
    pivot = sort_number[start_pointer]
    print('基准:',pivot)
    left = start_pointer
    right = end_pointer
    while(left != right):
        print(sort_type)
        while((left<right and sort_number[right]>pivot and sort_type == 0) or
              (left<right and sort_number[right]<pivot and sort_type == 1)):
            right-=1
        while((left<right and sort_number[left]<=pivot and sort_type == 0) or
              (left<right and sort_number[left]>=pivot and sort_type == 1)):
            left+=1
        if(left<right):
            item = sort_number[left]
            sort_number[left] = sort_number[right]
            sort_number[right] = item
            print('快速排序(双边循环):',sort_number)
            draw1(sort_number, sort_number[left])
    sort_number[start_pointer] = sort_number[left]
    sort_number[left] = pivot
    print('快速排序(双边循环):', sort_number)
    draw1(sort_number, sort_number[left])

    return left

def Unilateral_loop(sort_number,start_pointer,end_pointer,sort_type):
    if(start_pointer >= end_pointer):
        return
    pivot = sort_number[start_pointer]
    mark = start_pointer
    print('快速排序(单边循环)0:', sort_number)
    #print('基准:', pivot,'mark:',mark)
    for i in range(start_pointer+1,end_pointer+1):
        print("i:",i)
        if(sort_number[i]<pivot and sort_type == 0) or\
          (sort_number[i]>pivot and sort_type == 1):
            mark+=1
            print("对调:",sort_number[mark],"和",sort_number[i])
            p = sort_number[mark]
            sort_number[mark] = sort_number[i]
            sort_number[i] = p
            draw1(sort_number,sort_number[mark])
            print('sort_number:', sort_number[i], '基准:', pivot, 'mark:', mark)
            print('快速排序(单边循环)1:', sort_number)
    sort_number[start_pointer] = sort_number[mark]
    sort_number[mark] = pivot
    draw1(sort_number, sort_number[mark])
    print('快速排序(单边循环)2:', sort_number)
    print('基准:', pivot, 'mark:', mark)
    #print('快速排序(单边循环):', sort_number)
    return mark


def draw1(l, v):                # 绘制单个变化
    plt.cla()
    # 绘制列表柱状图
    x = [x + 1 for x in range(len(l))]
    bar = plt.bar(x, l)

    # 绘制数值
    for a, b in zip(x, l):
        plt.text(a, b + 0.05, '%.0f' % b, ha='center', va='bottom', fontsize=11)

    # 绘制当前移动的数
    for ba, y in zip(bar, l):
        if y == v:
            ba.set(color="red")
    plt.pause(0.01)




if __name__ == '__main__':
    sort_type = str(input("请输入排序类型【冒泡(bubble)鸡尾酒(cocktail)快速(quick)】\n:"))
    sort_way  = int(input("请输入排序方式【正序(0)倒序(1)】:"))
    print(sort_type,sort_way)
    if sort_type == str('bubble'):
        bubble(number,int(sort_way))
    elif sort_type == 'cocktail':
        Cocktail_sort(number,int(sort_way))
    elif sort_type == 'quick':
        sort_loop_type = int(input("请输入循环排序方式【双边循环(0)单边循环(1)】:"))
        Quick_sort(number,0,len(number)-1,sort_way,sort_loop_type)
    else :print("(!)输入错误,请重新输入")
    print("最终结果",number)
    plt.show()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值