基数排序、希尔排序、计数排序、桶排序

1、基数排序

import random from timewrap import *

def list_to_buckets(li, iteration):#这个是用来比较每一个位置的大小的数字

    """ 由于分红10个原本就是有序的因此排出来就是有序的。 :param li: 列表 :param iteration: 装桶是第几回迭代 :return: """ buckets = [[] for _ in range(10)] print('buckests',buckets) for num in li: digit = (num // (10 ** iteration)) % 10 buckets[digit].append(num) print(buckets) return buckets def buckets_to_list(buckets):#这个是用来出数的
    return [num for bucket in buckets for num in bucket] # li = []
    # for bucket in buckets:
    # for num in bucket:
    # li.append(num)
 @cal_time def radix_sort(li): maxval = max(li) # 10000
    it = 0 while 10 ** it <= maxval:#这个是循环用来,在之前一次排序的基础上在排序。
        li = buckets_to_list(list_to_buckets(li, it)) it += 1
    return li # li = [random.randint(0,1000) for _ in range(100000)]
li = [random.randint(0,10) for _ in range(10)] li=[5555,5525,9939,9999,6,3,8,9] s=radix_sort(li) print(s)

 

2、希尔排序

思路:git

  • 希尔排序是一种分组插入排序算法。
  • 首先取一个整数d1=n/2,将元素分为d1个组,每组相邻量元素之间距离为d1,在各组内进行直接插入排序;
  • 取第二个整数d2=d1/2,重复上述分组排序过程,直到di=1,即全部元素在同一组
  • 希尔排序每趟并不使某些元素有序,而是使总体数据愈来愈接近有序;最后一趟排序使得全部数据有序。

代码实现、算法

def insert_sort(li):#插入排序
    for i in range(1, len(li)): # i 表示无序区第一个数
        tmp = li[i] # 摸到的牌
        j = i - 1 # j 指向有序区最后位置
        while li[j] > tmp and j >= 0: #循环终止条件: 1. li[j] <= tmp; 2. j == -1
            li[j+1] = li[j] j -= 1 li[j+1] = tmp def shell_sort(li):#希尔排序 与插入排序区别就是把1变成d
    d = len(li) // 2
    while d > 0: for i in range(d, len(li)): tmp = li[i] j = i - d while li[j] > tmp and j >= 0: li[j+d] = li[j] j -= d li[j+d] = tmp d = d >> 1 li=[5,2,1,4,5,69,20,11] shell_sort(li) print(li)

 

希尔排序的复杂度特别复杂,取决于d,分组的长度2、位移运算符shell

3、计数排序

统计每一个数字出现了几回app

#计数排序 # 0 0 1 1 2 4 3 3 1 4 5 5
import random import copy from timewrap import * @cal_time def count_sort(li, max_num = 100): count = [0 for i in range(max_num+1)] for num in li: count[num]+=1 li.clear() for i, val in enumerate(count): for _ in range(val): li.append(i) @cal_time def sys_sort(li): li.sort() li = [random.randint(0,100) for i in range(100000)] li1 = copy.deepcopy(li) count_sort(li) sys_sort(li1)
复制代码

 计数排序这么快,为何不用计数排序呢?由于他是有限制的,你要知道列表中的最大数dom

若是一下来了一个很大的数,好比10000,那么占的空间就的这么大,ide

计数排序占用的空间和列表的范围有关系函数

解决这种问题的方法,能够用桶排序,都放进去能够在进行其余的排序。好比插入排序。post

4、桶排序

    在计数排序中,若是元素的范围比较大(好比在1到1亿之间),如何改造算法?spa

     桶排序,首先将将元素分在不一样的桶中,在对每一个桶中的元素排序。设计

多关键字排序

先对十位进行排序,再根据 十位进行排序

要用两个函数,一个用来装桶,一个用来出桶

默认10个桶,找到个位,十位,分别放在对应的桶里的位置

 

     桶排序的表现取决于数据的分布。也就是须要对不一样数据排序时采起不一样的分桶策略。

     平均状况时间复杂度:O(n+k)

     最坏状况时间复杂度:O(n+k)

     空间复杂度:O(nk)

    先分红若干个桶,桶内用插入排序。

 

例子

1:给两个字符串S和T,判断T是否为S的从新排列后组成的单词:

  s="anagram",t="nagaram",return true

   s='cat',t='car',return false

代码以下:

复制代码
s = "anagram" t = "nagaram"

def ss(s,t): return  sorted(list(s))==sorted(list(t)) y=ss(s,t) print(y)
复制代码

二、‘’

二维的坐标变成一维的坐标

X*b +y =i

(x,y) ->i

 

i//n----》x

i%n---->n

 

 1 def searchMatrix(matrix, target):  2     m = len(matrix)  3     # print('m', m)
 4     if m == 0:  5         return False  6     n = len(matrix[0])  7     if n == 0:  8         return False  9     low = 0 10     high = m * n - 1
11     # print('high',high)
12     while low <= high: 13         mid = (low + high) // 2
14         x, y = divmod(mid, n) 15         if matrix[x][y] > target: 16             high = mid - 1
17         elif matrix[x][y] < target: 18             low = mid + 1
19         else: 20             return True 21     else: 22         return False 23 
24 
25 s = [ 26     [1, 2, 3], 27     [4, 5, 6], 28     [7, 8, 9] 29 ] 30 # print(searchMatrix(s, 1))
31 # print(searchMatrix(s, 2))
32 # print(searchMatrix(s, 3))
33 # print(searchMatrix(s, 4))
34 # print(searchMatrix(s, 5))
35 # print(searchMatrix(s, 6))
36 print(searchMatrix(s, 7)) 37 # print(searchMatrix(s, 8))
38 # print(searchMatrix(s, 9))
View Code

 3.给定一个列表和一个整数,设计算法找两个数的小标,使得两个数之和为给定的整数。保证确定仅有一个结果。

     例如:列表[1,2,5,4]与目标整数3,1+2=3,结果为(0,1)

方式一:

方式二:

方式三

方式四和三同样

def twoSum(num, target): dict = {} for i in range(len(num)): print(dict) x = num[i] if target - x in dict: return dict[target - x], i dict[x] = i l = [1, 2, 5, 4] print(twoSum(l, 7))