提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
目录
前言
提示:以下是本篇文章正文内容,下面案例可供参考
一、数据结构
数据结构:逻辑结构、存储结构、操作定义与实现
逻辑结构:集合、线性、树形、图形
存储结构(物理):顺序存储、链式存储、索引存储、散列存储(哈希存储)
二、算法分析与优化
1.引例:最大公约数GCD
欧几里得算法:0<y<=x,若x mod y==0,gcd=y;否则 gcd(x,y)=gcd(y,x mod y);
2.时空复杂度的衡量
O 运行上限 可取等
Ω 运行下限
Θ 运行区间
o 运行上限但不取等
渐进表示法的计算 加法取最大,乘法直接相乘
例题:
主方法
3.分析应用
汉诺塔问题
#include<iostream>
using namespace std;
void hanoi(char a,char b,char c,int n){
if (n==1) cout<<a<<" -> "<<c<<endl; //直接移动到C柱,输出
else {
hanoi(a,c,b,n-1); //把上面a柱子上面n-1个,借助c柱移到B柱
cout<<a<<" -> "<<c<<endl; //将a柱子中第n个盘移动到c柱子,输出
Hanoi(b,a,c,n-1); //把剩下c柱子剩下n-1个,借助A柱从B柱移到C柱
}
}
int main(){
int n;
cin>>n;
hanoi('A','B','C',n);
}
最大子段和
最大子段和,前序子段在为正时才有利用意义。可以用一个变量存储开始位置,一个变量存储和,一个变量存最大和。当最大和更新时,更新字段起点和终点。当和变为负数时,重新设置起点,和从0开始重新记录。
空间复杂度优化
习题
三、线性表
1.顺序存储实现
2.链接存储实现
单链表:数据域data,链接域next
// head存储链表头,e[]存储节点的值,ne[]存储节点的next指针,idx表示当前用到了哪个节点
int head, e[N], ne[N], idx;
// 初始化
void init()
{
head = -1;
idx = 0;
}
// 在链表头插入一个数a
void insert(int a)
{
e[idx] = a, ne[idx] = head, head = idx ++ ;
//第idx个结点的数值为a,该结点next指针指向原头结点指针位置,头结点指针指向新idx,idx后移。
}
// 将头结点删除,需要保证头结点存在
void remove()
{
head = ne[head];
}
求长度:指针加cnt,一直后移至指针指向空。
查找:按序号,按值
插入:非头插时,计数找到第i-1个结点,若存在则申请一个新节点,值赋为x,新结点的next指向cnt=i-1时的next指针,cnt=i-1时的next指针指向新节点位置
删除:非头删,计数找到第i-1个结点,待删除结点位置为其next,将i-1个结点的next指针指向待删除结点的next位置。
双链表
int e[N], l[N], r[N], idx;
// 初始化
void init()
{
//0是左端点,1是右端点
r[0] = 1, l[1] = 0;
idx = 2;
//idx为1的结点,左指针指向0。头指针为r[0]指向头结点的索引,初始情况为1(idx)
}
// 在节点a的右边插入一个数x
void insert(int a, int x)
{
e[idx] = x;//赋值
l[idx] = a, r[idx] = r[a];//第idx个节点左指针指向节点a,右指针指向a的右指针位置
l[r[a]] = idx, r[a] = idx ++ ;//节点a的右侧节点,其左指针指向了idx,节点a的右指针=idx;
//值变,自己变,节点a变右指针,右侧数(原r[a])变左指针
}
// 删除节点a
void remove(int a)
{
l[r[a]] = l[a];//右侧数的左指针变为a的左指针
r[l[a]] = r[a];//左侧数的右指针变为a的右指针
}
带头结点的双向链表,可以设置一个空的头结点idx=0,真正的元素连接在空节点之后。
循环链表
链表终端节点的指针指向链表起始节点
静态链表
用数组存放线性表中的元素,给每组元素增加一个域,用来指示下一个元素在数组中的下标
块状链表
3.线性表的应用
一元多项式的加法
初始p1,p2指向两个多项式的第一个节点。
若节点的expon指数信息相同,则建立新节点,系数数据为和,指数数据不变。两指针同时后移。
若p1指数较大,则将p1信息copy建立新节点,p1指针后移。
大整数处理
加减法(O(n))
1.保证计算导入的a+b>0,符号位最后再加。
2.结果长度初始化为max(a.l,b.l),比较两组数据,用前导0对齐位数,并确定每组数据符号。
3.digit=x+y+carry
4.若比较的这一位 digit>=10,则carry=1,digit-=10;若digit<0,则carry=-1,digit+=10;否则carry=0
5.最后若仍有carry>0,最高位有进位,添加一位进位,长度+1.
6.检验并去除减法产生的前导零
乘法O(n^2)
此处digit数组从0开始计算,个位和个位相乘i+j=0,也即c的个位;十位与十位相乘,结果应当在百位,也即i+j=2。
第三步伪代码:
循环最低位到最高位,
tmp=c.digit[i]+carry;c.digit[i]=tmp%10;carry=tmp/10;
若最高位有进位,则进位=carry,length++;
四、其他线性表
广义表:元素可以是单元素,也可以是其他广义表
多维数组的顺序存储:
特殊矩阵:上三角、下三角矩阵存储->压缩空间
稀疏矩阵:0非常多,非0元素无规律。只存储非0项,用三元组表的顺序存储或链式存储(十字链表)来存储,每个节点通过两个指针域把同行、同列串起来。节点(数据Row\Col\Val、指针Right\Down)
舞蹈链:
总结
第二周习题
1.算法最坏情况下的时间复杂度是指算法求解输入规模为n的问题实例所需最多的基本运算次数
2.求时间复杂度O(n) i以2为公比等比数列递增,等比数列求和次数小于n
int sum = 0;
for(int i=1;i<n;i*=2)
for(int j=0;j<i;j++) sum++;
3.汉诺塔算法中,移动n个盘子到指定位置需要2^n-1次,其中最小的盘子移动2^(n-1)次。
4.位运算中,n&1=1表示n为奇数(2进制最后一位是1)
第三周习题
1.单链表中在指定位序插入或删除结点,需要先访问到指定位置所以时间复杂度还是O(n)。
复习题
1.数据结构可分为逻辑结构、存储结构和操作定义与实现。其中逻辑上又可以分为线性结构和非线性结构(树、图、集合)。
数据结构在计算机内存中表示是指数据的存储结构。于所使用的计算机无关的是逻辑结构。
2.在存储数据时,通常不仅要存储各数据元素的值,而且还要存储 C 。
A.数据的处理方法 B.数据元素的类型
C.数据元素之间的关系 D.数据的存储方法(由关系体现)
3.选取存储结构,不需要考虑结点的值如何。
4.数据元素是数据的基本单位(可由多个数据项组合而成),数据项是数据的最小单位,数据结构是带有结构的各数据元素的集合。一些表面上很不相同的数据可以有相同的逻辑结构。
5.若某表最常用的操作是在最后一个结点之后插入一个结点或删除最后一个结点,则采用 D 存储方式最节省运算时间。 D A.单链表 B.给出表头指针的单循环链表 C.双链表 D.带头结点的双循环链表
选D,双循环链表能够通过头结点的前驱就是尾结点,能够迅速找到尾结点,然后进行插入和删除操作
6.在一个具有n个结点的有序单链表中插入一个新结点并仍然保持有序的时间复杂度是 B 。
A.O(1) B.O(n) C.O(n2) D.O(nlog2n)