zoukankan      html  css  js  c++  java
  • 算法

    一.算法简单概念

    1.什么是算法?

    算法(Alorithm):一个计算过程,解决问题的方法

     

    2.递归

    递归的两个特点:

    1.调用自身

    2.结束条件

    看下面几个函数:

    3.时间复杂度

    时间复杂度:用来评估算法运行效率的一个东西

    类比生活中的一些时间,估计时间

    眨一下眼:一瞬间/几毫秒

    口算:28+66:几秒

    烧一壶水:几分钟

    睡一觉:几小时

    完成一个项目:几天/几星期/几个月

    飞船从地球飞出太阳系:几年

     总结:时间复杂度是用来估计算法运行时间的一个式子(单位)

    一般来说,时间复杂度高的算法比复杂度低的算法慢

    常见的时间复杂度(安效率排序)

    不常见的时间复杂度

    如何一眼判断时间复杂度?

    循环减半的过程:O(logn)

    几次循环就是n的几次方的复杂度

    4.空间复杂度

    空间复杂度:用来评估算法内存占用大小的一个式子

    空间换时间:程序开辟更多的内存空间来提高代码的运行效率

    二.列表查找

    列表查找:从列表中查找指定元素

    输入:列表,待查找元素

    输出:元素下标或未查找的元素

    顺序查找:从列表第一个元素开始,顺序进行搜素,直到找到为止

    二分查找:从有序列表的候选区data[0:n]开始,通过对待查找的值与候选区中间值的比较,可以使候选区减少一半

    data_set = [3, 4, 1, 6, 7, 8, 9, 2]
    
    # 循环遍历法
    def liner_search(data_set, value):
        for i in range(len(data_set)):
            if data_set[i] == value:
                return i
        return
    
    
    res = liner_search(data_set, 9)
    print(res)
    
    # 二分查找法
    def bin_search(data_set,value):
        low=0
        high=len(data_set)-1
        while low<=high:
            mid=(low+high)//2
            if data_set[mid]==value:
                return mid
            elif data_set[mid]>value:
                high=mid-1
            else:
                low=mid+1
    
    res=bin_search(data_set,9)
    print(res)
    
    # 递归二分查找法
    def bin_search_rec(data_set,value,low,high):
        if low<=high:
            mid=(low+high)//2
            if data_set[mid]==value:
                return mid
            elif data_set[mid]>value:
                return bin_search_rec(data_set,value,low,mid-1)
            else:
                return bin_search_rec(data_set, value, mid+1, high)
        else:
            return
    res=bin_search_rec(data_set,9,0,len(data_set)-1)
    print(res)

    三.列表排序

    1.列表排序

    • 将无序列表变为有序列表
    • 应用场景:
    • 1.各种榜单
    • 2.各种表格
    • 3.给二分排序用
    • 4.给其他算法用
    • 输入:无序列表
    • 输出:有序列表
    • 升序与降序

    2.排序low b 三人组:

    冒泡排序

    # 时间复杂:O(n^2)
    def bubble_sort(li):
        for i in range(len(li)-1):
            for j in range(len(li)-i-1):
                if li[j]>li[j+1]:
                    li[j],li[j+1]=li[j+1],li[j]
    
    li=[3,6,6,2,9,5,3,8]
    bubble_sort(li)
    print(li)

    如果冒泡排序中执行一趟二没有交换,则列表已经是有序状态,可以直接结算算法

    def bubble_sort(li):
        for i in range(len(li)-1):
            flag=False
            for j in range(len(li)-i-1):
                if li[j]>li[j+1]:
                    li[j],li[j+1]=li[j+1],li[j]
                    flag=True
            if not flag:
                return
    
    
    li=[1,2,3,4,5,6,8,9]
    bubble_sort(li)
    print(li)
    //golang语言的冒泡程序基本一样,go用的是数组
    
    package main
    
    import (
        "fmt"
    )
    
    func bubble(lis[]int)int{
        code:=0
        for i:=0;i<len(lis);i++{
            flag:=false
            for j:=0;j<len(lis)-i-1;j++{
                if lis[j]>lis[j+1]{
                    lis[j],lis[j+1]=lis[j+1],lis[j]
                    flag=true
                }
            }
            if !flag{
                return code
            }
        }
        return code
    }
    
    func main() {
        lis:=[]int{3, 4, 1, 6, 7, 8, 9, 2}
        bubble(lis)
        fmt.Println(lis)
    }

    选择排序

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

    重点:选出最小的数

    # 时间复杂度O(n^2)
    def select_sort(li):
        for i in range(len(li)-1):
            min_loc=i
            for j in range(i+1,len(li)):
                if li[j]<li[min_loc]:
                    min_loc=j
            if min_loc !=i:
                li[i],li[min_loc]=li[min_loc],li[i]
    
    li=[3, 4, 1, 6, 7, 8, 9, 2]
    select_sort(li)
    print(li)

    插入排序

    插入排序思路:列表被分为有序区和无序区两个部分,最初有序区只有一个元素,每次从无序区选择一个元素,插入到有序区的位置,直到无序区变空

    # 时间复杂度O(n^2)
    def insert_sort(li):
        for i in range(1,len(li)):
            tmp=li[i]
            j=i-1
            while j>=0 and tmp<li[j]:
                li[j+1]=li[j]
                j-=1
            li[j+1]=tmp
    
    li=[3, 4, 1, 6, 7, 8, 9, 2]
    insert_sort(li)
    print(li)

    3.三人组小结

    冒泡排序,插入排序,选择排序

    时间复杂度O(n^2)

    空间复杂度O(1)

    4.快速排序

    快速排序:快

    好写的排序算法里最快的

    快的排序算法里最好写的

    快排思路:取一个元素p(第一个元素),使元素p归位,列表被p分成两部分,左边都比p小,右边都比p大,递归完成排序

    关键点:整理,递归

    # 时间复杂度O(nlogn)
    def partition(data,left,right):
        tmp=data[left]
        while left<right:
            while left<right and data[right]>=tmp:
                right-=1
            data[left]=data[right]
            while left<right and data[left]<=tmp:
                left+=1
            data[right]=data[left]
        data[left]=tmp
        return left
    
    def quick_sort(data,left,right):
        if left<right:
            mid=partition(data,left,right)
            quick_sort(data,left,mid-1)
            quick_sort(data,mid+1,right)
    
    
    li=[3, 4, 1, 6, 7, 8, 9, 2]
    quick_sort(li,0,len(li)-1)
    print(li)
    //golang 的快速排序
    package main
    
    import "fmt"
    
    func partition(data[]int,left int,right int)int{
        tmp:=data[left]
        for i:=left;i<right;i++{
            for i:=left;i<right && data[right]>=tmp;i++ {
                right-=1
            }
            data[left]=data[right]
            for i:=left;i<right && data[left]<=tmp;i++ {
                left+=1
            }
            data[right]=data[left]
        }
        data[left]=tmp
        return left
    }
    
    func quick_sort(data[]int,left int,right int){
        if left<right{
            mid:=partition(data,left,right)
            quick_sort(data,left,mid-1)
            quick_sort(data,mid+1,right)
        }
    }
    
    func main() {
        li:=[]int{3,4,1,6,7,8,9,2}
        quick_sort(li,0,len(li)-1)
        fmt.Println(li)
    }

    5.计数排序

    计数排序思路:创建一个列表,用来统计每个数出现的次数

    #时间复杂度O(n^2)
    def
    count_sort(li,max_num): count=[0 for i in range(max_num+1)] for num in li: count[num]+=1 i=0 for num,m in enumerate(count): for j in range(m): li[i]=num i+=1 li=[3, 4, 1, 6, 7, 8, 9, 2] count_sort(li,max(li)) print(li)

    6.归并排序

    假设现在的列表分两段有序,如何将其合成为一个有序列表,这种操作称为一次归并

    归并的思路:

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

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

    # 时间复杂度O(nlogn),空间复杂度O(n)
    def merge(li,low,mid,high):
        i=low
        j=mid+1
        ltmp=[]
        while i <=mid and j<=high:
            if li[i]<=li[j]:
                ltmp.append(li[i])
                i+=1
            else:
                ltmp.append(li[j])
                j+=1
        while i<=mid:
            ltmp.append(li[i])
            i+=1
        while j<=high:
            ltmp.append(li[j])
            j+=1
        li[low:high+1]=ltmp
    
    def mergesort(li,low,high):
        if low<high:
            mid=(low+high)//2
            mergesort(li,low,mid)
            mergesort(li,mid+1,high)
            merge(li,low,mid,high)
    
    li=[3, 4, 1, 6, 7, 8, 9, 2]
    mergesort(li,0,len(li)-1)
    print(li)

    7.堆排序

    堆排思路:

    1. 建立堆
    2. 得到堆顶元素,为最大元素
    3. 去掉堆顶,将堆顶最后一个元素放到堆顶,此时可通过一次调整重新使堆有序
    4. 堆顶元素为第二大元素
    5. 重复步骤3,直到堆变空
    #时间复杂度O(nlogn)
    def
    sift(data,low ,high): i=low j=2*i+1 tmp=data[i] while j<=high: if j<high and data[j]<data[j+1]: j+=1 if tmp<data[j]: data[i]=data[j] i=j j=2*i+1 else: break data[i]=tmp def heap_sort(data): n=len(data) for i in range(n//2-1,-1,-1): sift(data,i,n-1) for i in range(n-1,-1,-1): data[0],data[i]=data[i],data[0] sift(data,0,i-1) li = [3, 4, 1, 6, 7, 8, 9, 2] heap_sort(li) print(li)

    8.希尔排序排序

    
    
    # 时间复杂度O(1.3n)
    def shell_sort(li):
    gap = len(li) // 2
    while gap > 0:
    for i in range(gap, len(li)):
    tmp = li[i]
    j = i - gap
    while j >= 0 and tmp < li[j]:
    li[j + gap] = li[j]
    j-=gap
    li[j + gap] = tmp
    gap //= 2
     
  • 相关阅读:
    天真
    投机取巧——Label控件变Line控件
    忽然想起当年我做水泥工的日子
    欢迎来到 wwh 的博客!
    Jenkins配置
    nginx启动停止脚本
    youget下载视频
    git同步代码
    Vue(26)eltree树形控件实现鼠标hover显示与隐藏
    Vue(27)vuecodemirror实现在线代码编译器
  • 原文地址:https://www.cnblogs.com/angelyan/p/10632859.html
Copyright © 2011-2022 走看看