数据结构绪论
2015-06-01 17:25
260 查看
预览:数据结构与算法的问题
什么是计算?评判DSA优劣的参照(直尺)?度量DSA性能的尺度(刻度)?
DSA性能度量的方法?DSA的设计和优化?
X1:理论模型和实际性能的区别
X2:DSA的极限(下界)
1、大O记号:常系数可以忽略,低次项也可以忽略;
几种记号的区别
2、循环、级数:可以用算数的方法描述,也可以用图形的方法描述
for(inti=0;i<n;i++)
for(intj=0;j<n;j++)
Operation(I,j);
算数级数:O(n2)
for(inti=0;i<n;i++)
for(intj=i;j<n;j++)
Operation(I,j);
算数级数:O(n2)
3、迭代与递归
(1)迭代:sum(int A[],n),直接迭代的方法
(2)递归:检查每个递归实例
如:sum(int A[],n)
{
return
n<1?0:sum(A[],n-1)+A[n-1];
}
分析每个递归实例,计算时间复杂度的时候,可以直接忽略掉sum,单个递归是O(1),所以最后得到的时间复杂度为O(1)*(n+1)=O(n);
T(n)=T(n-1)+O(1)…T(0)=O(1)
T(n)-n=T(n-1)-(n-1)=…=T(1)-1=T(0)
(3)二分递归:
sum(intA[],int low,int high)
{
if(low==high)return A[low];
intmid=(low+high)/2;
return sum(A,low,mid)+sum(A,mid+1,high);
}
4、分而治之
几何级数,与底层递归实例相同,为n,所以时间复杂度为O(n);
MAX2,从数组A[low,hi)中选择两个较大的数,要求比较操作次数最少
(1)首先找到最大的值,然后分为两段,分别比较
void Max2(A[],int low,int high,int&x1,int &x2)
{
//找出其中最大的值,n-1
for(int x1=low,int i=low+1;i<high;i++)
if(A[i]>A[x1]) x1=i;
//二分法,找出low到x1之间的最大值,x1-low-1
for(int x2=low,int i=low+1;i<x1;i++)
if(A[i]>A[x2]) x2=i;
//将找到的x2和后半部分进行比较,high-x1-1
for(int i=x1+1;i<high;i++)
if(A[i]>A[x2]) x2=i;
}
总的复杂度始终是2n-3;
(2)将两个指针分别指向x1,x2,然后每个值分别去和这两个值进行比较,它的
void Max2(A[],int low,int high,int &x1,int &x2)
{
If(A[x1=low]<A[x2]=low+1)swap(x1,x2);
for(inti=low+2,i<high;i++)
{
if(A[i]>A[x2])
if(A[x1]<A[x2=i])
Swap(x1,x2);
}
}
最好情况:1+(n-2)*1=n-1(相比第一次情况,第二次有了明显的进步)
最坏情况:1+(n-2)*2=2n-3
(3)二分递归
将其二分之后在进行递归之后比较
void Max2(A[],int low,int high,int &x1,int &x2)
{
If(low+1=high);//return
If(low+2=high);//return
Intmin=(low+high)/2;
Intx1L,x2L,x1R,x2R;
Max2(A,low,min,x1L,x2L);
Max2(A,min,high,x1R,x2R);
If(A[x1L]>A[x2L])
{ x1=x1L;
x2=(A[x2L]>A[x1R])?x2L:x1R;}
else
{x1=x2L;
X2=(A[x2R]>A[x1L])?x2R:x1L;}
}
所以总的复杂度是:T(n)=2*T(n/2)+2<5n/3-2
5.动态规划:找出最长的公共的子序列LCS
对于序列A[0,n],B[0,m]无非只有三种情况:
(1)若n=-1或者m=-1,则取空序列;
(2)减而治之:若A序列和B序列最后一个字母相同,则取A[0,n),B[0,n)的LCS+1;
(3)分而治之:若A序列和B序列最后一个字母不相同,则取A[0,n),B[0,n]或者是A[0,n],B[0,n)的LCS
什么是计算?评判DSA优劣的参照(直尺)?度量DSA性能的尺度(刻度)?
DSA性能度量的方法?DSA的设计和优化?
X1:理论模型和实际性能的区别
X2:DSA的极限(下界)
1、大O记号:常系数可以忽略,低次项也可以忽略;
几种记号的区别
2、循环、级数:可以用算数的方法描述,也可以用图形的方法描述
for(inti=0;i<n;i++)
for(intj=0;j<n;j++)
Operation(I,j);
算数级数:O(n2)
for(inti=0;i<n;i++)
for(intj=i;j<n;j++)
Operation(I,j);
算数级数:O(n2)
3、迭代与递归
(1)迭代:sum(int A[],n),直接迭代的方法
(2)递归:检查每个递归实例
如:sum(int A[],n)
{
return
n<1?0:sum(A[],n-1)+A[n-1];
}
分析每个递归实例,计算时间复杂度的时候,可以直接忽略掉sum,单个递归是O(1),所以最后得到的时间复杂度为O(1)*(n+1)=O(n);
T(n)=T(n-1)+O(1)…T(0)=O(1)
T(n)-n=T(n-1)-(n-1)=…=T(1)-1=T(0)
(3)二分递归:
sum(intA[],int low,int high)
{
if(low==high)return A[low];
intmid=(low+high)/2;
return sum(A,low,mid)+sum(A,mid+1,high);
}
4、分而治之
几何级数,与底层递归实例相同,为n,所以时间复杂度为O(n);
MAX2,从数组A[low,hi)中选择两个较大的数,要求比较操作次数最少
(1)首先找到最大的值,然后分为两段,分别比较
void Max2(A[],int low,int high,int&x1,int &x2)
{
//找出其中最大的值,n-1
for(int x1=low,int i=low+1;i<high;i++)
if(A[i]>A[x1]) x1=i;
//二分法,找出low到x1之间的最大值,x1-low-1
for(int x2=low,int i=low+1;i<x1;i++)
if(A[i]>A[x2]) x2=i;
//将找到的x2和后半部分进行比较,high-x1-1
for(int i=x1+1;i<high;i++)
if(A[i]>A[x2]) x2=i;
}
总的复杂度始终是2n-3;
(2)将两个指针分别指向x1,x2,然后每个值分别去和这两个值进行比较,它的
void Max2(A[],int low,int high,int &x1,int &x2)
{
If(A[x1=low]<A[x2]=low+1)swap(x1,x2);
for(inti=low+2,i<high;i++)
{
if(A[i]>A[x2])
if(A[x1]<A[x2=i])
Swap(x1,x2);
}
}
最好情况:1+(n-2)*1=n-1(相比第一次情况,第二次有了明显的进步)
最坏情况:1+(n-2)*2=2n-3
(3)二分递归
将其二分之后在进行递归之后比较
void Max2(A[],int low,int high,int &x1,int &x2)
{
If(low+1=high);//return
If(low+2=high);//return
Intmin=(low+high)/2;
Intx1L,x2L,x1R,x2R;
Max2(A,low,min,x1L,x2L);
Max2(A,min,high,x1R,x2R);
If(A[x1L]>A[x2L])
{ x1=x1L;
x2=(A[x2L]>A[x1R])?x2L:x1R;}
else
{x1=x2L;
X2=(A[x2R]>A[x1L])?x2R:x1L;}
}
所以总的复杂度是:T(n)=2*T(n/2)+2<5n/3-2
5.动态规划:找出最长的公共的子序列LCS
对于序列A[0,n],B[0,m]无非只有三种情况:
(1)若n=-1或者m=-1,则取空序列;
(2)减而治之:若A序列和B序列最后一个字母相同,则取A[0,n),B[0,n)的LCS+1;
(3)分而治之:若A序列和B序列最后一个字母不相同,则取A[0,n),B[0,n]或者是A[0,n],B[0,n)的LCS
相关文章推荐
- 斐波那契查找(超详解)
- 将无序Map准换为有序的TreeMap
- BZOJ - 2741: 【FOTILE模拟赛】L 分块+可持久化数据结构
- 【数据结构】栈的应用--行编辑程序(c++)
- 【数据结构】栈的应用--数制转换(c++)
- COJ983 WZJ的数据结构(负十七)
- 折半查找法的递归和非递归形式
- 图的邻接表存储和基本操作
- 图的数组(邻接矩阵)存储结构和基本操作
- 线性单链表的存储及基本操作(整理)
- 线性表存储和操作
- Python数据结构之——字典
- (数据结构第五章)广义表的头尾链表存储表示
- 【数据结构】用栈检测括号是否匹配
- 【数据结构】用C++编写队列及基本操作(包括插入,出队列,摧毁,清空等等)
- 【数据结构】用C++编写栈及基本操作(包括入栈,出栈,获得栈顶,摧毁,清空等等)
- 【数据结构】用C++实现双循环链表的各种操作(包括头删,尾删,插入,逆序,摧毁,清空等等)
- 【数据结构】用C++实现双链表的各种操作(包括头删,尾删,插入,逆序,摧毁,清空等等)
- 数据结构与算法分析学习笔记(1)--排序
- 几种常见的【排序】与【数据结构】