基本算法

希尔排序与桶排序,基数排序

4个算法例子

希尔排序:

      希尔排序是一种分组插入排序算法;

      首先去一个整数d1=n/2,将元素分为d1个组,每组相邻两元素之间距离为d1,在个组内进行直接插入排序;

     去第二个整数d2=d1/2,重复上述分组排序过程,直到d1=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)
View Code

  我们可以求出列表里每个元素出现的次数:代码如下:

 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 = 10):
    count = [0 for i in range(max_num+1)]
    print(count)
    for num in li:
        count[num]+=1
    li.clear()
    print(count)
    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)]
li = [random.randint(0,10) for i in range(10)]
li1 = copy.deepcopy(li)
count_sort(li1)
print(li1)
# sys_sort(li1)
桶排序的前戏

 

桶排序:

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

     桶排序,首先将将元素分在不同的桶中,在对每个桶中的元素排序。

 

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

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

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

     空间复杂度:O(nk)

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

 

     基数排序:

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)
View Code

 

例子

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)
View Code

2.

def searchMatrix(matrix, target):
    m = len(matrix)
    # print('m', m)
    if m == 0:
        return False
    n = len(matrix[0])
    if n == 0:
        return False
    low = 0
    high = m * n - 1
    # print('high',high)
    while low <= high:
        mid = (low + high) // 2
        x, y = divmod(mid, n)
        if matrix[x][y] > target:
            high = mid - 1
        elif matrix[x][y] < target:
            low = mid + 1
        else:
            return True
    else:
        return False


s = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
# print(searchMatrix(s, 1))
# print(searchMatrix(s, 2))
# print(searchMatrix(s, 3))
# print(searchMatrix(s, 4))
# print(searchMatrix(s, 5))
# print(searchMatrix(s, 6))
print(searchMatrix(s, 7))
# print(searchMatrix(s, 8))
# 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))
View Code

 

 

 

   

 

posted on 2018-02-01 17:18  黎明NB  阅读(160)  评论(0编辑  收藏  举报

导航