算法基础
来源:互联网 发布:linux gre over ipsec 编辑:程序博客网 时间:2024/06/08 12:54
算法定义
算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。
时间复杂度
时间频度
一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。
时间复杂度
刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律。为此,我们引入时间复杂度概念。 一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。n一般就是执行的次数,f(n)就是问题的规模
常见的时间复杂度
按数量级递增排列,常见的时间复杂度有:
常数阶O(1), 对数阶O(log2n), 线性阶O(n), 线性对数阶O(nlog2n), 平方阶O(n^2), 立方阶O(n^3),…, k次方阶O(n^k), 指数阶O(2^n) 。
常用排序
冒泡排序
冒泡排序详情
python代码
def bubble(array): count=0 length=len(array) exchange=length-1 #从0索引的 while exchange!=0: length=exchange exchange=0 for i in range(length): if array[i]>array[i+1]: temp=array[i+1] array[i+1]=array[i] array[i]=temp exchange=i+1 #exchange索引后的序列为顺序列表 count+=1 # print '第%d轮'%count, return array
选择排序
思想
选择排序的思想非常直接,不是要排序么?那好,我就从所有序列中先找到最小的,然后放到第一个位置。之后再看剩余元素中最小的,放到第二个位置……以此类推,就可以完成整个的排序工作了。可以很清楚的发现,选择排序是固定位置,找元素。相比于插入排序的固定元素找位置,是两种思维方式。不过条条大路通罗马,两者的目的是一样的。
代码
def select_sort(array): length=len(array) for i in range(0,length): index=i #记录最最小值的索引 for j in range(i+1,length): if array[index]>array[j]: index=j if (index!=i): temp=array[index] array[index]=array[i] array[i]=temp return array
插入排序
给定一个记录序列(r1,r2,…,rn),其相应的关键码分别是(k1,k2,…kn),排序是将这些记录排列成顺序为(r s1,r s2,… r sn)的一个序列,使得相应的关键码满足ks1<=ks2<=..<=ksn。
直接插入排序
思想
直接插入排序是插入排序中最简单的排序方法,类似于玩纸牌的时候整理手中纸牌的过程,其基本思想是:以此将待排序序列中的每一个记录插入到一个已经排好序的序列中,直到全部记录都排好序。(在排序问题中,通常讲数据元素称为记录)
排序过程
- 将整个待排序的记录序列划分为有序区和无序区,初始时有序区为待排序记录系列中的第一个记录,无序区包括所有剩余待排序的记录
- 将无序区的第一个记录插入到有序区的合适位置中,从而使无序区减少一个记录,有序区增加一个记录。
重复执行(2),直到无序区中没有记录为止
将第一个记录看成是初始有序区,然后从第二个记录起依次插入到这个有序区中,直到将第n个记录插入完毕
for(i=2;i<=n;i++){ 插入第i个记录}
一般情况下,在i-1个记录的有序区r[1]~r[i-1]中插入一个记录r[i]时,首先要查找r[i]的正确插入位置,最简单的,可以采用顺序查找,为了在寻找插入位置的过程中避免数组下标越界,在r[0]处设置“哨兵”,在自i-1起前往查找的过程中,同时后移记录
r[0]=r[i]for(j=i-1;r[0]<r[j];j--){ r[j+1]=r[j]}
退出循环,说明找到了插入的位置,因为r[j]刚刚比较完毕,所以r[j+1]为正确的插入位置,将待差记录插入到有序表中:
r[j+1]=r[0]
代码实现
def insert_sort_1(array): # 设置哨兵位 array.insert(0, 0) length = len(array) # 有序表的插入 for i in range(2, length): array[0] = array[i] for j in range(i - 1, 0, -1): # 元素往后移 if array[0] < array[j]: array[j + 1] = array[j] else: array[j + 1] = array[0] break #判断这个数是不是最小的 if array[0]<array[1]: array[1]=array[1] return array[1:]
折半插入排序
分析直接插入排序算法,由于寻找插入位置的操作是在有序区进行的,因此可以通过折半查找来实现,由此进行的插入排序称为折半插入排序
代码实现
def insert_sort_2(array): "折半插入排序" array.insert(0,0) length=len(array) for i in range(2,length): array[0]=array[i] #在有序表中折半查找 low=1 high=i-1 while low<=high: mid=(high+low)/2 if array[0]>array[mid]:low=mid+1 else:high=mid-1 #找到了位置 #移动记录 for j in range(i-1,low-1,-1): array[j+1]=array[j] print 'array=%s,mid=%s,low=%s,high=%s'%(array[0],mid,low,high), """ 或者: for j in range(i,low,-1): array[j]=array[j-1] """ array[low]=array[0] print array[1:] return array[1:]
希尔排序
希尔排序是对直接插入排序的一种改进,改进的着眼点是:
1. 若待排序记录按照关键码记录基本有序,直接插入排序的效率很高
2. 由于直接插入排序算法简单,则在待排序记录个数较少时,效率也很高
基本思想:
先将整个待排序记录序列分隔成若干个子序列,在子序列内分别进行直接插入排序,待整个序列基本有序的时候,在对全体记录进行一次直接插入排序
代码:
快速排序
快速排序详情
python代码
#coding:utf-8"快速排序"def quick_sort(array,first,end): if(first<end): "递归调用" "[23,13,35,6,19,50,28]----->[19, 13, 6, 23, 35, 50, 28]一次划分后的结果" pivot=partions(array,first,end) #接受返回的轴值的索引 #递归的对右侧的子序列进行快速排序 quick_sort(array,pivot+1,end) #递归的对左侧的子序列进行快速排序 quick_sort(array,first,pivot-1) return arraydef partions(array,first,end): "一次划分" while first<end: #进行右侧扫描 while first<end and array[first]<array[end]:end-=1 #在右侧找到了一个比轴值小的数,交换这两个数,然后这个数(包括这个数) # 前面的就排好了,最后让first加1 if(array[first]>array[end]): temp=array[first] array[first]=array[end] array[end]=temp first+=1 #进行左侧扫描 while first<end and array[first]<array[end]:first+=1 #在左侧找到了一个比轴值的大的数,将这个数和轴值交换,然后这个数后面的数就排好了,让end减1 if array[first]>array[end]: temp=array[first] array[first]=array[end] array[end]=temp end-=1 #return array "返回轴值的索引" return firstdef main(): array=[23,13,35,6,19,50,28] pass print partions(array,0,6) #[19, 13, 6, 23, 35, 50, 28]一次划分后的结果 print quick_sort(array,0,6) #[6, 13, 19, 23, 28, 35, 50]if __name__ == '__main__': main()
- 算法基础
- 算法基础
- 算法基础
- 基础算法
- 算法基础
- 基础算法
- 基础算法-
- 基础算法
- 算法基础
- 算法基础
- 基础算法
- 基础算法
- 算法基础
- 基础算法
- 基础算法
- 基础算法
- 基础算法
- 算法基础
- 数据库链接管理类Twisted adbapi.ConnectionPool
- java 加密 RSA(一)
- jzoj 4832. 【NOIP2016提高A组集训第3场10.31】高维宇宙 网络流或状压dp
- wifi详解-1(基本常识)
- Android Studio创建Assets Folder、JNI文件夹、AIDL文件夹
- 算法基础
- Ajax使用FormData对象实现无刷新上传文件
- Linux学习--第八天--acl、SetUID、SetGID、chattr、lsattr、sudo
- activity的四种启动模式
- web前端性能优化的方法
- CocosStuidio(十三)排行榜
- react-native-art-绘图入门
- async和await 用法
- c的学习之路(1)