图解python书-4.排序

本文介绍了多种排序算法,包括冒泡排序、选择排序、插入排序、希尔排序、合并排序、快速排序和基数排序。阐述了逻辑排序和直接排序的区别,还详细说明了每种排序算法的实现思路,如冒泡排序通过双层循环比较大小,基数排序是按位数分配模式排序。

排序算法

排序分为逻辑排序和直接排序

逻辑排序只改变指针的指向(分组排序汇总)

直接排序交换存储数据的位置

1.冒泡排序

变量双层,一层个数次数,二层个数次数-i加上判断和上一个数字的大小

import random


def sort_bubble(data):
    len_Data=len(data)
    for i in range(len_Data):
        for j in range(len_Data-i-1):
            if(data[j]>data[j+1]):
                data[j+1],data[j]=data[j],data[j+1]
        print(i+1,data)
data=[16,25,39,27,12,8,45,63]
sort_bubble(data)

1 [16, 25, 27, 12, 8, 39, 45, 63]
2 [16, 25, 12, 8, 27, 39, 45, 63]
3 [16, 12, 8, 25, 27, 39, 45, 63]
4 [12, 8, 16, 25, 27, 39, 45, 63]
5 [8, 12, 16, 25, 27, 39, 45, 63]
6 [8, 12, 16, 25, 27, 39, 45, 63]
7 [8, 12, 16, 25, 27, 39, 45, 63]
8 [8, 12, 16, 25, 27, 39, 45, 63]

2.选择排序法

变量双层,一层个数次数,二层个数次数-i加上判断和当前最小或最大的大小

def lect_sort(data):
    len_data=len(data)
    for i in range(len_data-1):
        small_index=i
        for j in range(i+1,len_data):
            if(data[small_index]>data[j]):
                small_index=j
        data[small_index],data[i]=data[i],data[small_index]

        print(data)
data=[16,25,39,27,12,8,45,63]
lect_sort(data)

[8, 25, 39, 27, 12, 16, 45, 63]
[8, 12, 39, 27, 25, 16, 45, 63]
[8, 12, 16, 27, 25, 39, 45, 63]
[8, 12, 16, 25, 27, 39, 45, 63]
[8, 12, 16, 25, 27, 39, 45, 63]
[8, 12, 16, 25, 27, 39, 45, 63]
[8, 12, 16, 25, 27, 39, 45, 63]

3.插入排序法

每次先排序好前面的,然后把下一个放到合适的位置上(把其他的往后移,然后放入要放的数字)

def insert_sort(data):
    len_data=len(data)
    for i in range(1,len_data):
        temp=data[i]
        no=i-1
        while no>=0 and temp<data[no]:
            data[no+1]=data[no]
            no-=1
        data[no+1]=temp
        print(data)
data=[16,25,39,27,12,8,45,63]
insert_sort(data)
[16, 25, 39, 27, 12, 8, 45, 63]
[16, 25, 39, 27, 12, 8, 45, 63]
[16, 25, 27, 39, 12, 8, 45, 63]
[12, 16, 25, 27, 39, 8, 45, 63]
[8, 12, 16, 25, 27, 39, 45, 63]
[8, 12, 16, 25, 27, 39, 45, 63]
[8, 12, 16, 25, 27, 39, 45, 63]

4.希尔排序法

减低插入排序的搬移次数,通过间隔减少
比插入排序多了一个jump,插入排序是no=i-1,希尔排序是no=i-jump

def xier_sort(data):
    len_data=len(data)
    jump=len_data//2
    while(jump!=0):
        for i in range(jump,len_data):
                temp=data[i]
                no=i-jump
                while(no>=0 and temp<data[no]):
                    data[no+jump]=data[no]
                    no-=jump
                data[no+jump]=temp
        print(jump,data)
        jump//=2
data=[16,25,39,27,12,8,45,63]
xier_sort(data)
4 [12, 8, 39, 27, 16, 25, 45, 63]
2 [12, 8, 16, 25, 39, 27, 45, 63]
1 [8, 12, 16, 25, 27, 39, 45, 63]

5.合并排序法

前提:待排序的数组本身是有序的
插入的时候同时枚举待合并的数列,然后插入到一个新的数列里面

list1=[20,45,51,88,9999]
list2=[98,10,23,15,9999]
list3=[]
# 将待合并的数组分别进行预先排序
def select_sort(data):
    len_data=len(data)-1
    for i in range(len_data-1):
        small_index=i
        for j in range(i+1,len_data):
            if(data[small_index]>data[j]):
                small_index=j
        data[small_index],data[i]=data[i],data[small_index]

        # print(data)
    return data
# 合并程序,进行两个数组的合并,就是枚举两个数据,插入到新数列里面,从小到大插入
def My_Merge():
    global list1
    global list2
    global list3
    len_data1=len(list1)-1
    len_data2=len(list2)-1
    index1=0
    index2=0

    for i in range(len_data1+len_data2):
        if(list1[index1]<list2[index2]):
            list3.append(list1[index1])
            index1+=1
        else:
            list3.append(list2[index2])
            index2+=1
        print(list3)
list1=select_sort(list1)
list2=select_sort(list2)
print(list1)
print(list2)
My_Merge()
[20, 45, 51, 88, 9999]
[10, 15, 23, 98, 9999]
[10]
[10, 15]
[10, 15, 20]
[10, 15, 20, 23]
[10, 15, 20, 23, 45]
[10, 15, 20, 23, 45, 51]
[10, 15, 20, 23, 45, 51, 88]
[10, 15, 20, 23, 45, 51, 88, 98]

7.快速排序法

  1. 获得一个中间值
  2. 小于中间值的放到左边,大于中间值的放到右边
  3. 分别按照第二的步骤处理左右两边,知道剩余一个为止
import random
#生成n个随机梳理
def inputarr(size):
    data=[]
    for i in range(size):
        data.append(random.randint(1,100))
    return data
def quick_sort(data,size,lf,rg):

    if lf<rg: #右边索引比左边索引大
        lf_idx=lf+1  # lf为被比较值
        # while(data[lf_idx]<data[lf]):
        #     if lf_idx+1>size-1:
        #         break
        #     lf_idx+=1
        while data[lf_idx] <data[lf] and lf_idx+1<size: # 将最左边的数字作为中间数,比他小的时候lf_idx加,比他大的时候,看右边,如果也出现了比lf小的时候就交换这两个位置

            lf_idx+=1
        rg_idx=rg
        while(data[rg_idx]>data[lf]):
            rg_idx-=1
        while lf_idx<rg_idx:
            data[lf_idx],data[rg_idx]=data[rg_idx],data[lf_idx]
            lf_idx+=1
            while data[lf_idx]<data[lf]:
                lf_idx+=1
            rg_idx-=1
            while data[rg_idx]>data[lf]:
                rg_idx-=1
        data[lf],data[rg_idx]=data[rg_idx],data[lf]   # 最后将lf(被比较值)和rg_idx交换位置
        print(data)
        quick_sort(data,size,lf,rg_idx-1)
        quick_sort(data,size,rg_idx+1,rg)
size=int(input("请输入要排序的数字个数"))
data=[99,10,12,56,11,2,90]
quick_sort(data,size,0,size-1)
[90, 10, 12, 56, 11, 2, 99]
[2, 10, 12, 56, 11, 90, 99]
[2, 10, 12, 56, 11, 90, 99]
[2, 10, 12, 56, 11, 90, 99]
[2, 10, 11, 12, 56, 90, 99]
def quick_sort2(data,size,lf,rf):
    print('正在排序范围:',data[lf:rf+1])
# 1. 根据data[lf]来划分左右部分
    if(len(data[lf:rf+1])>0):
        temp=data[lf]
    else:
        temp='none'
    if(rf>lf):
        lf_idx=lf+1
        while(data[lf_idx]<data[lf]):
            if lf_idx+1>size-1:
                break
            lf_idx+=1
        rg_index=rf
        while(data[lf]<data[rg_index]):
            rg_index-=1
        while(rg_index>lf_idx):
            data[lf_idx],data[rg_index]=data[rg_index],data[lf_idx]
            lf_idx+=1
            while(data[lf_idx]<data[lf]):
                lf_idx+=1
            rg_index-=1
            while(data[lf]<data[rg_index]):
                rg_index-=1
        data[lf],data[rg_index]=data[rg_index],data[lf]
        print('比较值:',temp,'排序结果:',data)
        quick_sort2(data,size,lf,rg_index-1)
        quick_sort2(data,size,rg_index+1,rf)
size=int(input("请输入要排序的数字个数"))
data=inputarr(size)
quick_sort2(data,size,0,size-1)
print('最终结果:',data)

正在排序范围: [45, 92, 43, 4, 83, 65, 49, 44, 58, 18]
比较值: 45 排序结果: [44, 18, 43, 4, 45, 65, 49, 83, 58, 92]
正在排序范围: [44, 18, 43, 4]
比较值: 44 排序结果: [4, 18, 43, 44, 45, 65, 49, 83, 58, 92]
正在排序范围: [4, 18, 43]
比较值: 4 排序结果: [4, 18, 43, 44, 45, 65, 49, 83, 58, 92]
正在排序范围: []
正在排序范围: [18, 43]
比较值: 18 排序结果: [4, 18, 43, 44, 45, 65, 49, 83, 58, 92]
正在排序范围: []
正在排序范围: [43]
正在排序范围: []
正在排序范围: [65, 49, 83, 58, 92]
比较值: 65 排序结果: [4, 18, 43, 44, 45, 58, 49, 65, 83, 92]
正在排序范围: [58, 49]
比较值: 58 排序结果: [4, 18, 43, 44, 45, 49, 58, 65, 83, 92]
正在排序范围: [49]
正在排序范围: []
正在排序范围: [83, 92]
比较值: 83 排序结果: [4, 18, 43, 44, 45, 49, 58, 65, 83, 92]
正在排序范围: []
正在排序范围: [92]
最终结果: [4, 18, 43, 44, 45, 49, 58, 65, 83, 92]

基数排序法

根据个十百千位这样分开排序
LSD为从最右边的位数开始比较
MSD为从最左边的位数开始比较
很特殊,不是元素之间的比较操作,而是一种分配模式排序方式

def radix(data,size):
    n=1 # 从个位开始
    while n<=100:
        tmp=[[0]*100 for row in range(10)]  # 存个位数为0-9的,每个为100个,用来暂存
        for i in range(size):
            m=(data[i]//n)%10  # 取位数值
            tmp[m][i]=data[i] # 将位数值放到tmp这个二维数组里面,m为个十百千位,i为位数的分类值
        k=0
        for i in range(10): # 将tmp的值取出来放到data里面,不能影响其前后顺序,所以需要list
            for j in range(size):
                if tmp[i][j]!=0:
                    data[k]=tmp[i][j]
                    k+=1
        print(n,data)
        n*=10
size=int(input('请输入排序列表个数'))
data=inputarr(size)
radix(data,size)
print(data)
1 [50, 51, 1, 2, 52, 22, 93, 24, 55, 5, 85, 65, 56, 7, 27, 77, 7, 47, 58, 19]
10 [1, 2, 5, 7, 7, 19, 22, 24, 27, 47, 50, 51, 52, 55, 56, 58, 65, 77, 85, 93]
100 [1, 2, 5, 7, 7, 19, 22, 24, 27, 47, 50, 51, 52, 55, 56, 58, 65, 77, 85, 93]
[1, 2, 5, 7, 7, 19, 22, 24, 27, 47, 50, 51, 52, 55, 56, 58, 65, 77, 85, 93]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

厨 神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值