时间复杂度
- 执行的次数==时间
- 随着输入规模n的增大,T(n)增长最慢的算法为最优算法。 时间复杂度用O()表示。
时间复杂度(复杂度由小到大)分别为:O(1),O(n),O(n^2)
- 如何分析算法的时间复杂度(如何推导大O阶)
· 时间复杂度所耗费的时间从大到小依次是:
- O(1) < O(logn) < O(n2) < O(n3) < O(2n) < O(n!) < O(n^n)
· 大O阶就是运行次数中保留最大次数的那个项。(以下四点步骤地概括)
- 用常数1代替运行时间中的所有加法常数
- 在修改后的运行次数函数中,只保留最高阶项
- 如果最高阶项存在且不是1 ,则去除与这个项相乘的常数
- 得到的最后结果就是大O阶
平均运行时间是期望的运行时间;
最坏运行时间是一种保证,我们所提到的运行时间都是最坏情况的运行时间。
空间复杂度
算法的空间复杂度通过计算算法所需要的存储空间实现,S(n)=O(f(n)),n为问题的规模,f(n)为语句关于n所占存储空间的函数。
顺序存储结构
·线性表的顺序存储结构是指用一段地址连续的存储单元依次存储线性表的数据元素
·顺序存储结构封装三个属性:
- 存储空间的起始位置,数组data,它的存储位置就是线性表存储空间的存储位置
- 线性表的最大存储容量:数组的长度MaxSize(存放线性表的储存空间的总长度,初始化后不变)
- 线性表的当前长度:length(当前长度是线性表中元素的个数,会变化)
·地址计算方法:LOC(ai)=LOC(a1)+(i-1)*c
- a1是起始地址
- c是一个地址所占用的字节数
·线性表顺序存储结构的优缺点:
- 在存,读数据时,不管是哪个位置,时间复杂度都是O(1);在插入,删除数据时,时间复杂度都是O(n)——线性表顺序存储结构比较适合元素个数比较稳定,所以更多的操作是存取数据的应用
- 插入和删除操作需要移动大量元素,线性表长度变化较大时,难以确定存储空间的容量,容易造成存储空间的“碎片”
- 无需为表示表中元素之间的逻辑关系而增加额外的存储空间,可以快速地存取表中任意位置地元素
数据类型的定义
InitList(*L)//初始化操作建立一个空的线性表L
ListEmpty(L)//判断线性表是否为空表
//若线性表为空,返回true,否则返回false
ClearList(*L)//将线性表清空
GetElem(L,i,*e)//(重要)将线性表L中的第i个位置元素值返回给e
LocateElem(L,e)//(重要)在线性表L中查找与给定值e相等的元素
//如果查找成功,返回该元素在表中序号表示成功,否则返回0表示失败
ListInsert(*L,i,e)//(重要)在线性表L中第i个位置插入新元素e
ListDelete(*L,i,*e)//删除线性表L中第i个位置元素,并用e返回其值
ListLength(L)//(重要)返回线性表L的元素个数
例:GetElem(L,i,*e)——获取
int GetElem ( SqList L, int i, int *e )
{
if ( i < 1 || i > L->length || L->length == 0 )
return 0;
*e = L->data[i-1];
return 1;
}
改进(包含宏定义):
#define Ok 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
Status GetElem ( SqList L, int i, ElemType *e )
{
if ( i < 1 || i > L->length || L->length == 0 )
return ERROR;
*e = L->data[i-1];
return OK;
}
例:ListInsert(*L,i,e)——插入
int ListInsert ( SqList *L, int i, int e )
{
int k;
if ( i < 1 || i > L->length + 1 )
return 0;
if ( L->length >= MAXSIZE )
return 0;
if ( i <= L->length ) //若插入数据位置不在表尾
for ( k = L->length - 1; k >= i - 1; --k )
L->data[k+1] = L->data[k];
L->data[i-1] = e;
L->length++;
return 1;
}
改进(包含宏定义):
Status ListInsert ( SqList *L, int i, ElemType e ){
int k;
if ( i < 1 || i > L->length + 1 )
return ERROR;
if ( L->length >= MAXSIZE )
return ERROR;
if ( i <= L->length )
for ( k = L->length - 1; k >= i - 1; --k )
L->data[k+1] = L->data[k];
L->data[i - 1] = e;
L->length++;
return OK;
}
例:ListDelete(*L,i,*e)——删除
int ListDelete ( SqList *L, int i, int *e ){
int k;
if ( i < 1 || i > L->length )
return 0;
if ( L->length == 0 )
return 0;
*e = L->data[i-1];
if ( i < L->length )
//如果删除的不是最后一个位置(删除的不是最后一个元素)
for ( k = i; k < L->length; ++k )
L->data[k-1] = L->data[k];
L->length--;
return 1;
}
改进(包含宏定义):
Status ListDelete ( SqList *L, int i, ElemType *e ){
int k;
if ( i < 1 || i > L->length )
return ERROR;
if ( L->length == 0 )
return ERROR:
*e = L->data[i-1];
if ( i < L->length )
for ( k = i; k < L->length; ++k )
L-data[k-1] = L-data[k];
L->length--;
return OK;
}