笔记-数据结构进阶
笔记:数据结构
1.语言+算法+数据结构=信息奥赛
数据的存放方式,体现了数据结构
数据结构=数据+结构,结构指储存、操作、关系。
2.线性结构
2.1集合的表示
若用set储存,则需要用insert插入元素,因为set是一颗红黑树。
由于set里面元素单调,可用\(O(\log{n})\)二分法查找,
数组:连续的一段储存空间
可\(O(1)\)查询特定编号的元素,
链表:链式结构
若动态指针实现,则可以做到:
struct node{
int data;
node *next;
};
node *head;
核心代码:
head=new node;
r=head;//r是一个工作指针,也就是“扫描头”
while(cin>>x){
p=new node;
p->data=x;
p->next=NULL;
r->next=p;
r=p;
}
应用:图的链接表储存法
1.动态分配内存空间
2.快速插入一个节点
//在p和q之间插入数值x
node *r=new node;
r->data=x;
r->next=&q;
p.next=r;
若用静态数组来描述链表,则用\(data_i\)表示第i个元素的data值,用\(next_i\)表示第i个元素的下一个元素值
应用:链式前向星
struct node{
int data;
}V[nmax];
struct edge{
int to,w,next;
}E[mmax];
实现:
void add(int u,int v,int w)
{
E[++cnt].next=head[u];
E[cnt].to=v;
E[cnt].w=w;
head[u]=cnt;
}
栈:FILO
应用:进制转换,括号匹配,中缀表达式转后缀
\(3*8-(6-2)/(3+4)\) ==> \(3,8,*,6,2,-,3,4,+,/,-\)
\(f(t)=-ce^{-kt}+\int{f_e(t)e^{-kt}dt}\) ==>
\(t,f=-c,-k,t,*,exp,*,t,f_e,-k,t,*,exp,*,\int{dt},+\)
表达式压栈规则:
\(op(v)=\begin{cases}pop(),\text{pri}(v)<\text{pri}(s.head())\\push(v),else\end{cases}\)
单调栈:
\(op(v)=\begin{cases}pop(),v<s.head()\\push(v),else\end{cases}\)
这样栈里的元素就是单调的了。
e.g.Histogram
给出一个柱状统计图,他的每一个项目的宽度是1,高度和具体问题有关,求柱状图中最大长方形面积。
即:给定\(\{a_i\}\),求出\(ans=\max\limits_{1\leq{j}<i\leq{n}}{\{(j-i+1)*h_{i,j}\}}\)
其中\(h_{i,j}=\min\limits_{i\leq{\mu}\leq{j}}a_{\mu}\)
int top=0,s[maxn];
int Area=0;
for(int i=1;i<=n;i++)
{
while(top&&h[s[top]]>=h[i])
--top;
L[i]=(top==0?1:s[top]+1);
s[++top]=i;
}
e.g.求最长不下降子序列
优化单调栈:\(\text{insert}(i,x)=\begin{cases}\text{insert}(i-1,x),v>s_i\\s_i=v,else\end{cases}\)
队列:FIFO
e.g.集合划分
给定集合\(A=\{a_n\}\)和由01矩阵构成的冲突关系\(R_{ij}=\begin{cases}0,\text{i,j无冲突关系}\\1,\text{i,j有冲突关系}\end{cases}\),且\(R_{ij}=R_{ji}\),\(R_{ii}=0,i,j=1,2,...,n\),将\(A\)划分成\(k\)个互不相交的子集,且对于任意子集\(A_i\)和\(x,y\in{A_i}\),都有\(R_{xy}=0\),求出使得k最小的划分方案。
分析:申请以下变量:
int R[nmax][nmax];//冲突矩阵
int newr[nmax];//工作数组
int cq[nmax];//循环队列
int result[nmax];//记录分组数
int group=1;//记录总共组数
工作过程:
\((1)\ cq_i\gets{A_i}\quad newr\gets{\{0\}}\quad result\gets{\{0\}}\)
\((2)\ newr_i\gets{R_{\mu,i}}\)
\((3)\ v\gets{cq.\text{head()}}\quad cq.\text{pop()}\)
\(\quad \text{op}(v)=\begin{cases}\text{push}(v),\quad R_{\mu,v}=1\\newr_i\gets{R_v,i},\quad else\end{cases}\)
$(4)\ \mu \ \text{from 1 to n do (1) to (3) until}\ cq \ \text{is empty} $
e.g.滑动窗口