文章目录
- 1、时间复杂度
- 1.2、大O渐进表示法
- 1.3、递归算法时间复杂度计算
- 2、空间复杂度
- 3、顺序表
- 1、概念
- 2、静态顺序表
- 3、动态顺序表
- 1、创建结构体(头文件中创建)
- 2、销毁链表
- 3、初始化结构体
- 4、打印函数
- 5、内存扩容
- 6、顺序表任意位置插入数据
- 7、顺序表任意位置删除数据
1、时间复杂度
1.2、大O渐进表示法
大O符号:(big O notation)是用于描述函数渐进行为的数学符号
推导大O阶的方法:
1、用常数 1 取代运行时间中所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项
3、如果最高阶项存在且不是 1,则去除这个项相乘的常数,得到的结果就是大O阶
1.3、递归算法时间复杂度计算
1、每次函数调用时间是O( 1 ) 那么就看他的递归次数
2、每次函数调用时间不是O( 1 ) 那么就看他递归调用次数中的累加
2、空间复杂度
1、空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用储存空间大小的度量
2、空间复杂度计算的是变量的个数
3、空间复杂度的计算规则和时间复杂度类似,也用大O渐进表示法
注:函数运行时所需的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间就已经确定好了,因此空间复杂度主要由函数在运行时候显示申请的额外空间来确定
3、顺序表
1、概念
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。(顺序表和数组的差别在于,顺序表要求数据要从0开始,依次连续的存储)
2、静态顺序表
直接利用宏定义将顺序表的所需的空间开辟出来,但是这样做有两个问题。
1、开小了空间不够用
2、开大了空间存在浪费
3、动态顺序表
优点:
连续物理空间,方便下标随机访问。
缺点:
1、插入数据,空间不足时需要扩容,扩容操作有性能消耗
2、头部或中间位置插入删除数据,需要进行挪动数据操作,效率较低
3、可能存在一定程度上的空间浪费,不能按需申请和释放空间
1、创建结构体(头文件中创建)
typedef int SLDataType;
//动态顺序表
typedef struct SeqList
{
SLDataType* a;//指向动态开辟的数组
int size;//记录存储多少个值
int capacity;//存储空间大小
}SL,SeqList;//将struct SeqList定义成 SL 或者 SeqList
2、销毁链表
void SeqListDestroy(SeqList* psl)
{
assert(psl);//断言不为空
free(psl->a);
psl->a = NULL;
psl->capacity = psl->size = 0;
}
3、初始化结构体
void SeqListInit(SeqList* psl)
{
assert(psl);//断言的作用,让结构体指针不为空
psl->a = NULL;//将指针初始化为空指针
psl->size = 0;//size记录结构体存储数据个数
psl->capacity = 0;//capacity记录结构体开辟的空间大小
}
4、打印函数
void SeqListPrint(SeqList* psl)//测试代码时候需要用上打印函数
{
assert(psl);//断言结构体不为空
for (int i = 0; i < psl->size; ++i)
{
printf("%d", psl->a[i]);
}
printf("\n");
}
5、内存扩容
void SeqListCheckCapacity(SeqList* psl)
{
assert(psl);
// 如果满了,我们要扩容
if (psl->size == psl->capacity)
{
size_t newCapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;
//问号表达式进行条件判断,如果内存为0就扩容4,如果有内存就扩大两倍
SLDataType* tmp = realloc(psl->a, sizeof(SLDataType)*newCapacity);
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
else
{
psl->a = tmp;
psl->capacity = newCapacity;
}
}
}
6、顺序表任意位置插入数据
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)
{
// 暴力检查方法
assert(psl);
// 温和检查方法
if (pos > psl->size)
{
printf("pos 越界:%d\n", pos);
return;
//exit(-1);
}
SeqListCheckCapacity(psl);
size_t end = psl->size;
while (end > pos)
{
psl->a[end] = psl->a[end-1];
--end;
}
psl->a[pos] = x;
psl->size++;
}
7、顺序表任意位置删除数据
void SeqListErase(SeqList* psl, size_t pos)
{
assert(psl);
assert(pos < psl->size);
size_t begin = pos + 1;
while (begin < psl->size)
{
psl->a[begin - 1] = psl->a[begin];
++begin;
}
psl->size--;
}
int SeqListFind(SeqList* psl, SLDataType x)
{
assert(psl);
for (int i = 0; i < psl->size; ++i)
{
if (psl->a[i] == x)
{
return i;
}
}
return -1;
}