zoukankan      html  css  js  c++  java
  • 基本算法

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

    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

       

  • 相关阅读:
    一起谈.NET技术,深入ASP.NET 2.0的提供者模型(2) 狼人:
    一起谈.NET技术,从.NET中委托写法的演变谈开去(上):委托与匿名方法 狼人:
    一起谈.NET技术,将Flash 嵌入WPF 程序 狼人:
    一起谈.NET技术,数组排序方法的性能比较(中):Array.Sort<T> 实现分析 狼人:
    人一生当中最应该珍惜的十种人
    《程序员的第一年》复习一下C#的【封装 多态 继承 简单计算器源码实例】
    myeclipse 修改模板
    三星将在百思买零售店内开设1400家体验店
    谷歌Q3推Android本 蚕食自己平板市场
    Spring Setting
  • 原文地址:https://www.cnblogs.com/1a2a/p/8400084.html
Copyright © 2011-2022 走看看