算法

一.算法简单概念

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
 

 

posted @ 2019-03-31 20:06  Maple_feng  阅读(343)  评论(0编辑  收藏  举报