• 向量


    1.抽象数据类型(ADT)

    ADT=数据模型+定义在该模型上的一组操作

    DS=基于某种特定语言,实现ADT的一整套算法

    2.向量是数组的抽象与泛化,由一组元素按照线性次序封装而成。

    3.动态空间管理:在即将发生上溢时,适当的扩大数组内部的容量

    扩容时,内部开辟一个新的数组空间,将原来数组中存放的数据一一填充至新的数组空间,收回原来数组分配的空间。

    1)容量递增策略:追加固定大小的容量:capacity+=INCREMENT(累计增容时间O(n^2),分摊增容时间O(n))

    2)容量加倍策略:追加加倍数量大小的容量:new_capacity=m*old_capicity(累计增容时间O(n),分摊增容时间O(1))

    4.去除无序向量中重复的元素

    思路1:从第二个元素开始向后循环,在该元素之前的元素区间中查找是否存在与当前元素相同的值,若不存在则向后继续循环,若存在则删除当前元素//O(n^2)

    思路2:先对需删除的重复元素做标记,然后再统一删除,稳定性保持,但因查找长度更长,从而导致更多的比对操作

    思路3:先排序,后去重//O(nlogn)

    5.有序向量

    无序序列中,总有一对相邻元素逆序,有序序列中,任意一对相邻元素顺序

    因此,相邻逆序对的数目,可用以度量向量的逆序程度

    有序向量的去重操作

    思路1:在有序向量中,重复的元素必然相互紧邻构成一个区间,因此,每一区间只需保留单个元素即可  #O(n^2)

    li=[1,1,3,8,44,44,54,55,55,55,55,55,67,90,100,100]
    counter=len(li)
    i=0
    while i<counter-1:
        if li[i]==li[i+1]:
            del li[i+1]
            counter=len(li)
        else:
            i=i+1
    print(li)

    思路二:
    原算法中每一次移动只能移动一个单元,若能以重复区间为单位,成批删除雷同元素,性能将改进  #O(n)

    li=[1,1,3,8,44,44,54,55,55,55,55,55,67,90,100,100]
    counter=len(li)
    i=0
    temp=0
    while i<counter-1:
        if li[i]==li[i+1]:
            temp=temp+1 #while elem=55 temp=4
        else:
            move_num=counter-(i+1)
            while move_num>0:
                li[i-temp+1]=li[i+1]
                move_num=move_num-1
        i=i+1
    print(li)

    直接变换下标,涉及到数组的算法采用多个下标进行操作会比较简便

    li=[1,1,1,1,1,1,3,8,44,44,54,55,55,55,55,55,67,90,100,100]
    counter=len(li)
    i=0
    j=1
    while j<counter-1:
        if li[i]==li[j]:
            j=j+1
        else:
            i=i+1
            li[i]=li[j]
            j=j+1
    
    print(li)

     6.二分查找

    def search(seq,aim):
        lo=0;
        hi=len(seq)-1
        while lo<hi:
            mid=int((lo+hi)/2)
            if(li[mid]<aim):
                lo=mid+1
            elif(aim<li[mid]):
                hi=mid
            else:
                return mid
    li=[1,2,9,12,42,54,98,110]
    aim=9
    index=search(li,aim)
    print(index,li[index])

    如何更为精细地评估查找算法的性能?
    考查关键码(if语句的比较)的比较次数,即查找长度

    7.斐波那契查找:

    思路及原理:前述二分查找版本的效率仍有改进余地,因为不难发现转向左右分支前的关键码比较次数不等,而递归深度却相同

    若能通过递归深度的不均衡,对转向成本的不均衡进行补偿,平均查找长度应能进一步缩短

    比如,若设n=fib(k)-1,则可取mi=fib(k-1)-1,黄金比例,最优解

    8.改进方案

    思路1:无论向左或向右转向,都只进行一次比较,即所有分支只有2个方向,而不再是3个方向,e<x或x<=e

    改进后,只有当元素数目hi-lo=1时,才判断该元素是否命中 while(1<hi-lo)

    改进语义约定:

    1)当有多个命中元素时,必须返回最靠后者

    2)失败时,应返回小于e的最大者

    9.冒泡排序

     冒泡排序的改进,用一个变量进行记录,标明整体是否有序,每一次相邻元素比较后进行判断,若发生交换则不是整体有序

    li=[11,33,4,208,22,89,182,32,69,358,222]
    for j in range(1,len(li)):#为外层循环次数
        issorted=True
        for i in range(len(li)-j):
            current_value=li[i]
            next_value=li[i+1]
            if current_value > next_value:
                temp=li[i]
                li[i]=li[i+1]
                li[i+1]=temp
                issorted=False
        if issorted:
           break
    print(li)

     反例:前小半部分为乱序排列,后大半部分为严格有序的序列

    改进后

    li=[3,32,6,43,24,11,22,33,44,55,66,77,88,99]
    lt=[3,6,32,24,11,22,43,33,44,55,66,77,88,99]
    lq=[3,6,32,24,11,22,33,43,44,55,66,77,88,99]
    hi=len(li)
    i=1
    while i<hi:
        last=0
        for j in range(len(li)-i):
            if li[j]>li[j+1]:
                temp=li[j]
                li[j]=li[j+1]
                li[j+1]=temp
                last=j
        i=i+1
        hi=last
    
    print(li)


    10.归并排序,时间复杂度为O(nlogn)

    原理:分治策略

    序列一分为二 //O(1)

    子序列递归排序// 2*T(n/2)

    合并有序子序列//O(n)

    li=[1,3,23,32,52,66,99,1111,2222,3333]
    lj=[4,5,12,53,108,232]
    
    result=[]
    i=0
    j=0
    
    while i<len(li) or j<len(lj):
        if i<len(li) and (j>=len(lj) or li[i]<=lj[j]):
            result.append(li[i])
            i=i+1
        if j<len(lj) and (i>=len(li) or li[i]>lj[j]):
            result.append(lj[j])
            j=j+1
    
    print(result)
  • 相关阅读:
    微信小程序通过getPhoneNumber后台PHP解密获取用户手机号码
    设置API:wx.openSetting,wx.getSetting使用说明(示例:地图授权与取消授权后的重新授权)
    微信小程序之上传图片和图片预览
    微信小程序上传图片(前端+PHP后端)
    微信小程序拒绝授权后重新拉起授权窗口
    微信小程序如何使用 Git 实现版本管理和协作开发
    配置同时使用 Gitlab、Github、Gitee(码云) 共存的开发环境
    linux 系统下Anaconda的安装【安装python3.6环境首选】
    利用phpqrcode二维码生成类库合成带logo的二维码并且用合成的二维码生成海报(二)
    利用phpqrcode二维码生成类库和imagecopymerge函数制拼接图片的经验(一)
  • 原文地址:https://www.cnblogs.com/lvjygogo/p/8526175.html
Copyright © 2020-2023  润新知