一、衡量一个程序是否高效
1.时间复杂度:
数据量增长与程序运行时间的比例关系以函数描述称为时间渐进复杂度函数,简称时间复杂度
O(c) > O(logn) > O(n) > O(nlogn) > O(n^2) > O(n^3) > O(2^n)
2.空间复杂度:
数据量增长与程序所占用空间的比例关系称为空间复杂度
3.程序 = 数据结构 + 算法
二、数据结构
1、数据之间的关系
1.逻辑结构:
- 线性结构
一对一 表
- 非线性结构
一对多 树
多对多 图
2.存储结构:
-
顺序存储结构
-
链式存储结构
-
离散存储
-
索引存储
2、常见的数据结构:
顺序表、链式表、顺序栈、链式栈、顺序队列、链式队列 、树 二叉树
三、顺序表
顺序表的主要操作为增、删、改、查
1、增(向顺序表中插入新数据)
cpp
//末尾添加
int AppendSeqList(SeqList *pTmpList, DataType TmpData)
{
if (IsFullSeqList(pTmpList))//判断顺序表是否满
{
return -1;
}
pTmpList->pData[pTmpList->cLen] = TmpData;
pTmpList->cLen++;
return 0;
}
//指定位置插入
int PosInsertSeqList(SeqList *pTmpList, int Pos, DataType TmpData)
{
int n = 0;
if (IsFullSeqList(pTmpList))
{
return -1;
}
//错误的插入位置
if (!(Pos >= 0 && Pos <= pTmpList->cLen))
{
return -2;
}
for (n = pTmpList->cLen; n > Pos; n--)
{
pTmpList->pData[n] = pTmpList->pData[n-1];
}
pTmpList->pData[Pos] = TmpData;
pTmpList->cLen++;
return 0;
}
2、删(删除顺序表中的指定数据)
cpp
int DeleteSeqList(SeqList *pTmpList, int Pos)
{
int i = 0;
int n = 0;
if (IsEmptySeqList(pTmpList))
{
return -1;
}
if (!(Pos >= 0 && Pos < pTmpList->cLen))
{
return -2;
}
for (n = Pos; n < pTmpList->cLen-1; n++)
{
pTmpList->pData[n] = pTmpList->pData[n+1];
}
pTmpList->cLen--;
return 0;
}
3、改(修改顺序表中的指定数据)
cpp
int ForeachSeqList(SeqList *pTmpList, int (*pFun)(void *Element, void *arg), void *arg)
{
int i = 0;
int ret = 0;
for (i = 0; i < pTmpList->cLen; i++)
{
ret = pFun(&pTmpList->pData[i], arg);
if (ret != 0)
{
return -1;
}
}
return 0;
}
使用该函数遍历顺序表内元素,符合条件的对其进行修改
4、查(查询顺序表中的指定数据)
cpp
int ForeachSeqList(SeqList *pTmpList, int (*pFun)(void *Element, void *arg), void *arg)
{
int i = 0;
int ret = 0;
for (i = 0; i < pTmpList->cLen; i++)
{
ret = pFun(&pTmpList->pData[i], arg);
if (ret != 0)
{
return -1;
}
}
return 0;
}
使用该函数遍历顺序表内元素,符合条件的可对其进行计数和打印
四、链表
1、与顺序相比链表的优缺点
1.空间可以不连续,访问元素不方便
2.链表需要更大的空间存放数据和节点地址
3.链表空间不连续,使得理论上长度是无限的
4.链表的插入和删除效率很高
2、链表的分类:
1.单向链表
2.双向链表
3.循环链表
4.内核链表