0
点赞
收藏
分享

微信扫一扫

十种经典的排序算法的python实现

南陵王梁枫 2022-03-30 阅读 66

文章目录


前言

以下是十种经典排序算法的python代码展示,现已将代码封装为类,有错误的地方希望大家批评指正呀,大家共同探讨共同成长,加油加油!!


一、涉及的排序算法

十种经典的排序算法分别是:冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序和基数排序。(具体的介绍就不详细说明了,这位博主有很详细的介绍排序算法详细介绍

二、代码

代码如下(示例):

主代码


class sort:
    def swap(self,nums,m,n):
        tmp=nums[m]
        nums[m]=nums[n]
        nums[n]=tmp


    '''
    bubble是冒泡排序,针对数组里的元素进行n-1轮排序
    每轮会把最大/小的元素移动到数组末尾
    '''
    def bubble(self,nums):
        Len=len(nums)
        if Len==1:
            return nums
        for i in range(Len-1,-1,-1):
            for j in range(i):
                if nums[j]>nums[j+1]:
                    sort.swap(self,nums,j,j+1)          #类中调用其他方法,要带类名
        return nums
    '''
    select选择排序
    内层循环应该是无序区,实际操作的是无序区
    '''
    def select(self,nums):
        Len = len(nums)
        if Len==1:
            return nums
        for i in range(Len-1):
            Min = nums[Len - 1]
            Min_pos = Len - 1
            for j in range(i,Len-1):
                # print('i={},j={}'.format(i,j))
                if nums[j]<Min:
                    Min=nums[j]
                    Min_pos = j                     #找到无序区最小的数
            # print('i={},Min_pos={}'.format(i,Min_pos))
            sort.swap(self, nums, i, Min_pos)        #交换最小序号和新的最小值的序号
            # print('nums={}'.format(nums))
                # print('Min={},Min_pos={}'.format(Min,Min_pos))
        '''
        错误:这种只是把最小的放在了第一个,要正着来
     
        for i in range(Len - 2,-1,-1):
            Min = nums[Len - 1]
            Min_pos = Len - 1
            for j in range(i, Len - 1):
                print('i={},j={}'.format(i,j))
                if nums[j] < Min:
                    Min = nums[j]
                    Min_pos = j  # 找到无序区最小的数
            print('i={},Min_pos={}'.format(i,Min_pos))
            sort.swap(self, nums, i, Min_pos)  # 交换最小序号和新的最小值的序号
            print('nums={}'.format(nums))
            # print('Min={},Min_pos={}'.format(Min,Min_pos))
            '''
        return nums
    '''
    插入排序:insert
    内层循环应该是有序区,因为是从无序区插入有序区,实际需要操作的是有序区
    '''
    def insert(self,nums):
        Len = len(nums)
        if Len==1:
            return nums
        for i in range(1,Len):
            for j in range(Len-1):
                if nums[i]<nums[j]:
                    nums.insert(j,nums.pop(i))
                    break
        return nums
    '''
    希尔排序:shell
    关键在于间隔序列的选择!!!(提前设定好间隔序列,动态定义间隔序列)
    '''
    def shell(self,nums):
        Len = len(nums)
        if Len==1:
            return nums
        gap=Len
        while gap>1:
            gap=gap//2
            for pos in range(gap,Len,gap):
                while pos:
                    if nums[pos] < nums[pos-gap]:
                        tmp=nums[pos]
                        nums[pos]=nums[pos-gap]
                        nums[pos-gap]=tmp
                        pos = pos - gap
                    else:
                        '''
                         关注跳出条件,不要浪费计算资源
                         因为是从头到尾排序,之前的已经是排好的,所以后面的只需要从前面的序列里面最大
                        '''
                        break
        return nums

    '''
    归并排序:merge
    n路归并
    '''
    def merge(self,nums,l,mid,r):
        # print('before sort:{}'.format(nums))
        if l==r:
            return nums
        else:
            tmp=[]
            i = l
            j = mid + 1
            while i<=mid and j<=r:
                 if nums[i]<=nums[j]:
                     tmp.append(nums[i])
                     i = i + 1
                 else:
                     tmp.append(nums[j])
                     j = j + 1
            '''
            在取值的过程中有一个数组取完了,就会把另一个数组剩下的元素全部添加
            因为已经排好序
            '''
            while i <= mid:
                tmp.append(nums[i])
                i =i + 1
            while j <= r:
                tmp.append(nums[j])
                j = j + 1
            '''
            把拎出来的临时数组赋值回去,因为每次的标号不一定相同因此得注意!!
            '''
            for i in range(l, r + 1):
                nums[i] = tmp[i - l]
            return tmp
    def mmerge(self,nums,l,r):
        if l>=r:
            return nums
        mid=(r+l)//2
        self.mmerge(nums, l, mid)
        self.mmerge(nums, mid + 1, r)
        self.merge(nums,l,mid,r)
        return nums
    '''
    快速排序:quick
    '''

    def quick(self,nums,l,r):
        # print('before sort:{}'.format(nums))
        # print('l={},r={}'.format(l,r))
        stu = l
        if l>=r:
            return nums,stu
        for j in range(l,r):
            for i in range(l+1,r):
                # print('i={},stu={}'.format(i,stu))
                if nums[i]<nums[stu] and i>stu:
                    self.swap(nums,stu,i)
                    stu=i
                    # print('stu={}'.format(stu))
                elif nums[i]>nums[stu] and i<stu:
                    self.swap(nums, stu, i)
                    stu = i
                    # print('stu={}'.format(stu))
        return stu
    def mquick(self,nums,l,r):
        if l>=r:
            return nums
        '''
        分区操作,找到每个数组段的区间中点
        '''
        stu = self.quick(nums,l,r)
        '''
        每个区分别操作
        '''
        self.mquick(nums,l,stu)
        self.mquick(nums, stu+1, r)

        return nums
    '''
    堆排序:heap
    '''
    def heap(self,nums,end):        #堆操作

        pos=(end-1)//2
        for i in range(pos,-1,-1):
            l = 2 * i + 1
            r = 2 * i + 2
            # print('i={},l={},r={}'.format(i,l,r))
            if nums[i]<nums[l]:
                self.swap(nums, i, l)
            if r<=end and nums[i]<nums[r]:
                self.swap(nums, i, r)
            # print('nums:',nums)
        return nums

    def mheap(self,nums):
        print('before sort:{}'.format(nums))
        Len=len(nums)
        if Len==1:
            return nums

        for end in range(Len-1,0,-1):
            # print('end={}'.format(end))
            self.heap(nums,end)
            self.swap(nums,0,end)

        return nums
    '''
    计数排序:count
    '''
    def count(self,nums):
        Len=len(nums)
        Min=nums[0]
        Max=nums[0]
        for i in nums:
            if i>Max:
                Max = i
            elif i<Min:
                Min = i
        count=[0]*(Max-Min+1)
        k=0
        for i in nums:
            count[i-Min]+=1
        for i,ele in enumerate(count):
            if ele!=0:
                for j in range(ele):
                    nums[k]=i+Min
                    k=k+1
        return nums
    '''
    桶排序:bucket
    '''
    def bucket(self,nums):
        Len=len(nums)
        Min = nums[0]
        Max = nums[0]
        for i in nums:
            if i>Max:
                Max = i
            elif i<Min:
                Min = i
        Min=Min//10
        Max=Max//10
        tmp=[[0 for i in range(Len)] for j in range(Max-Min+1)]                   #浅拷贝,改变一个复制的数组部分也会变,只适用于一维
        stmp = []
        for j in range(Max - Min + 1):
            k=0

            for i in nums:
                if (i//10)==j:
                    tmp[j][k] = i
                    k=k+1

            self.mquick(tmp[j],0,k)
            stmp = stmp + tmp[j][0:k]
            # stmp = self.cat(tmp[j], k)
        nums=stmp

        return nums

    '''
    基数排序:Radix 
    '''
    def radix(self,nums):
        Len=len(nums)
        '''
        找到最大值
        判断最高位
        '''
        Max = nums[0]
        for i in nums:
            if i > Max:
                Max = i
        bin=0
        z=Max
        while z:
            z = z// 10
            bin = bin + 1
        # print('bin={}'.format(bin))
        for j in range(0,bin): #bin = bin-1的原因是怕遗漏了最大值是0的数组 取不到bin
            Min = (nums[0]%(10*pow(10,j)))//pow(10,j)
            Max = (nums[0]%(10*pow(10,j)))//pow(10,j)
            # print('before Min={},Max={}'.format(Min,Max))
            for i in nums:
                i=i%(10*pow(10,j))//pow(10,j)
                # print('i={}'.format(i))
                if i > Max:
                    Max = i
                elif i < Min:
                    Min = i
            # print('after find Min={},Max={}'.format(Min,Max))
            count = [[-1 for i in range(Len)] for k in range(Max - Min + 1)]
            x=0
            for i in nums:
                k=i%(10*pow(10,j))//pow(10,j)       #代表每一位数字
                # print('k={}'.format(k))
                count[k - Min][x] = i
                # print('k - Min={},x={},count={}'.format(k - Min,x,count))
                x=x+1
            k=0
            for i in range(Max - Min + 1):
                for j in range(Len):
                    if count[i][j]>=0:
                        nums[k]=count[i][j]
                        k=k+1

        return nums

调用方式、示例

nums=[2,4,32,66,8,5,1,9,100,23,3291]
sort_ins=sort()                         #创建一个对象,再调用相关的方法
print('after sort:{}'.format(sort_ins.radix(nums)))

总结

应该是有一些编写不足的方面,希望大家批评指正,但是经过测试,所有代码都是正确的。

举报

相关推荐

0 条评论