zoukankan      html  css  js  c++  java
  • 常用算法

    程序=数据结构+算法

    递归(复习)

    特点:

    调用自身

    结束条件

    def func1(x):
    if x>0:
    func1(x-1)
    print(x)
    func1(10)

    列表查找

    顺序查找:就是for循环,一个一个找

    二分查找:必须是有序的列表

    代码:

     1 def bin_search(li,val):
     2     low = 0
     3     high = len(li) -1
     4     while low <=high:
     5         mid = (low+high)//2
     6         if li[mid] ==val:
     7             return mid
     8         elif li[mid] >val:
     9             high = mid -1
    10         else:
    11             low = mid +1
    12     return None
    13 li=list(range(1000))
    14 print(bin_search(li,3))

    LOW B三人组

    冒泡:列表每两个相邻的数,如果前面比后面的大,那么交换这两个数的位置

    选择:一趟遍历记录中最小的数,放到第一个位置,再一趟遍历剩余列表中的数字,继续放置

    插入:每次从无序区选择一个元素,插入到有序区,直到无序区为空

    冒泡代码:

     1 def bubble_sort(li):
     2     for i in range(len(li)-1):
     3         flag = False
     4         for j in range(0, len(li)-i-1):
     5             if li[j] > li[j+1]:
     6                 li[j], li[j+1] = li[j+1], li[j]
     7                 flag=True
     8         if not flag:  #如果走了一趟都没有变化,说明已经排好了,直接跳出循环
     9             break
    10 
    11 li=list(range(100))
    12 random.shuffle(li)
    13 print(li)
    14 bubble_sort(li)
    15 print(li)

     选择排序代码:

     1 def select_sort(li):
     2     for i in range(len(li)-1):
     3         min_loc = i
     4         for j in range(i+1, len(li)): #该循环总能找到最小值
     5             if li[j] < li[min_loc]:
     6                 min_loc = j
     7         li[min_loc], li[i] = li[i], li[min_loc]
     8 
     9 li=list(range(100))
    10 random.shuffle(li)
    11 print(li)
    12 select_sort(li)
    13 print(li)

     插入排序代码

     1 def insert_sort(li):
     2     for i in range(1, len(li)):#从第二个开始循环
     3         tmp = li[i] #把抽到的牌先临时存起来
     4         j = i - 1  #前面那张牌的下标
     5         while j>=0 and li[j]>tmp:  #从第二个开始循环,且前面的数大于后面
     6             li[j+1]=li[j] #满足条件j的位置往后挪一位,tmp不插入
     7             j = j - 1 #再把前一张牌往前挪一位,去比较下一张
     8         li[j+1] = tmp  #插入tmp
     9 
    10 li=list(range(100))
    11 random.shuffle(li)
    12 print(li)
    13 insert_sort(li)
    14 print(li)

    NB三人组

    快排:好写排序里面最快的

    取一个元素P,通过某种方式使P归位,列表被分成两部分,左边的都比P小,右边的都比P大,完成归位;

    分别对左右递归,当列表中小于两个元素,排序完成。

    代码:

    
    
    def partition(data, left, right):
    tmp = data[left] #取第一个数(要归位的数)临时存起来,此时左边有空位了
    while left < right:
    while left<right and data[right] >= tmp: #从右边找只要right比tmp大,就一直找
    right -= 1
    data[left]=data[right] #不满足while条件,说明右边比左边小,将右边的数值,覆盖到左边
    while left<right and data[left] <= tmp: #从左边找
    left += 1
    data[right]=data[left]
    data[left]=tmp #不满足while条件,说明left=fight,归位
    return left

    def quick_sort_x(data, left, right):
    if left < right:#说明至少还有俩元素,需要继续递归
    mid = partition(data, left, right) #mid值指已经归位的下标,把列表分成两部分
    quick_sort_x(data, left, mid - 1)
    quick_sort_x(data, mid + 1, right)

    @cal_time
    def quick_sort(data):
    quick_sort_x(data, 0, len(data)-1)
    print(data)

    li=list(range(10))
    random.shuffle(li)
    print(li)
    quick_sort(li)
     

     堆排序:

    import random
    def sift(li, left, right):
        i = left
        j = 2 * i + 1
        tmp = li[left]
        while j <= right:
            if j+1 <= right and li[j] < li[j+1]:
                j = j + 1
            if tmp < li[j]:
                li[i] = li[j]
                i = j
                j = 2 * i + 1
            else:
                break
        li[i] = tmp
    
    
    def heap_sort(li):
        n = len(li)
        for i in range(n//2-1, -1, -1): #建立堆
            sift(li, i, n-1)
        for i in range(n-1, -1, -1):    #挨个出数
            li[0], li[i] = li[i],li[0]
            sift(li, 0, i-1)
    li=list(range(100000))
    random.shuffle(li)
    print(li)
    heap_sort(li)
    print(li)

     归并排序

    假设现在的列表分两段有序,如何将其合成一个有序列表

    这个过程称为一次归并

     分解:将列表越分越小,直至分成一个元素

    一个元素是有序的

    合并:将两个有序列表归并,列表越来越大

     代码:

     1 import random
     2 def merge(li, left, mid, right):
     3     i = left
     4     j = mid + 1
     5     ltmp = []
     6     while i <= mid and j <= right:   #左边右边都没排完
     7         if li[i] < li[j]:
     8             ltmp.append(li[i])  #升序排列
     9             i += 1
    10         else:
    11             ltmp.append(li[j])
    12             j += 1
    13     while i<= mid: #左边剩下了
    14         ltmp.append(li[i])   #依次挨个追加
    15         i += 1
    16     while j <= right:
    17         ltmp.append(li[j])
    18         j += 1
    19     li[left:right+1] = ltmp
    20 
    21 def _merge_sort(li,left,right):
    22     if left < right:
    23         mid = (left+right)//2
    24         _merge_sort(li,left,mid)
    25         _merge_sort(li,mid+1,right)
    26         #print(li[left:right+1])
    27         merge(li,left,mid,right)
    28         #print(li[left:right+1])
    29 
    30 @cal_time
    31 def merge_sort(li):
    32    _merge_sort(li, 0, len(li)-1)
    33 
    34 li=list(range(100))
    35 random.shuffle(li)
    36 print(li)
    37 merge_sort(li)
    38 print(li)

    时间装饰器代码

    import time
    
    def cal_time(func):
        def wrapper(*args, **kwargs):
            t1 = time.time()
            x = func(*args, **kwargs)
            t2 = time.time()
            print("%s running time %s secs."%(func.__name__, t2-t1))
            return x
        return wrapper

     一般情况下,就运行时间而言

    快排  < 归并排序  < 堆排序

     快排:极端情况下排序效率低

    归并排序:需要额外的内存开销

    堆排序:在快的排序算法中相对比较慢





  • 相关阅读:
    正则表达式
    特殊符号作用
    sed
    scp
    EOF
    env
    JAVA进阶5
    JAVA进阶4
    JAVA进阶3
    JAVA进阶2
  • 原文地址:https://www.cnblogs.com/liumj0305/p/8088092.html
Copyright © 2011-2022 走看看