一.线性结构
1.顺序线性表
1.1 线性结构是一种基本的数据结构,具有单一前驱和后继的数据关系描述。
1.2 线性表的存储结构分为顺序存储和链式存储。
1.3 顺序线性表的元素间的逻辑关系无需占用额外的空间来存储。
1.4 一般地,以LOC(a1a_1a1)表示线性表中第一个元素的存储位置,在顺序存储结构中,第i个元素aia_iai的存储位置为
LOC(ai)=LOC(a1)+(i−1)∗LLOC(a_i) = LOC(a_1) + (i-1)*L LOC(ai)=LOC(a1)+(i−1)∗LL表示表中每个元素所占用空间的字节数。
1.5 顺序线性表的优点是可以随机存储表中的元素,缺点是插入和删除元素需要移动元素。
1.6插入删除操作需要移动元素个数的期望值
(1) 在长度为n的线性表中插入元素时,共有n+1个插入位置,在位置1处插入元素需要移动n个元素,在n位置处插入元素,需要移动一个元素,则可知在**位置i处插入元素,需要移动的元素个数为n+1 - i,**假设在n+1个位置插入元素的概率相等,则概率为:
1n+1\frac{1}{n+1} n+11则插入元素的期望为
Einsert=∑i=1n+11n+1(n+1−i)=n2E_{insert} = \displaystyle\sum_{i=1}^{n+1} \frac{1}{n+1}(n+1 - i) = \frac{n}{2} Einsert=i=1∑n+1n+11(n+1−i)=2n
(2) 删除元素时,有n个元素可删除的元素,删除第i个元素需要移动的元素个数为n-i,则期望为:
Edelete=∑i=1n1n(n−i)=n−12E_{delete} = \displaystyle\sum_{i=1}^{n} \frac{1}{n}(n - i) = \frac{n-1}{2} Edelete=i=1∑nn1(n−i)=2n−1
1.7 因此,插入和删除的时间复杂度为O(n)。
2.链式线性表
2.1 通过指针域来存储元素之间的逻辑关系,若节点中只有一个指针域,则称为线性链表,具有插入和删除元素不需要移动元素的优点。
2.2 在单链表中,在p所指节点后面插入新节点:
s->next = p->next;
p->next = s
2.3 在单链表中删除p所指节点的后继节点:
q = p->next;//记住需要删除的节点,用于其释放内存
p->next = p->next->next;
free(q);
插入,删除节点都需要从插入或删除的节点入手,结合图中所示,书写首尾衔接,方便快速写出正确的代码。
2.4 在实际应用中,为了简化对链表状态的判定和处理,特别引入一个不存储数据元素的节点,称之为头节点,将其作为链表的第一个节点并令头指针指向该节点。
2.5 双向链表,具有连个指针域,分别指出当前元素的直接前驱和直接后继。循环链表,在单链表的基础上,令表尾节点的指针指向链表的第一个节点。注意区分两者的区别。
2.6 双向链表的删除和插入操作,front表示前驱,next表示后继。
在p节点之前插入节点s:
s->front = p->front;
p->front->next = s;
s->next = p;
p->front = s;
删除节点p:
p->front->next = p->next;
p->next->front = p->front;
free(p);
3. 栈和队列
3.1 在栈中进行插入和删除操作的一端称为栈顶。
3.2 栈的存储结构:顺序存储和链式存储。采用顺序存储结构的栈称为顺序栈,在这种存储方式下,需要预新申请栈的存储空间。
3.3 栈的典型应用包括表达式求值,括号匹配等,其次将递归过程转换成非递归过程,也需要利用栈来实现。
3.4 在对队列中,允许插入元素的一端称为队尾(Rear),允许删除元素的一端称之为队头(Front)。顺序存储的队列,可以通过求余运算来实现环状结构。
元素入队和元素出队列;
Q.rear = (Q.rear +1) % MAXSIZE;// 采用下标加1的方式表示入队和出队
Q.front = (Q.front +1) % MAXSIZE;
3.5 当头指针和为指针相等时,表示队列为空,当尾指针的下一个位置为头指针是表示队列满,或者设置一个队列满的标志是区分队列的空与满。
3.6 链式队列,采用给队列添加一个头节点,并令头指针指向该节点。因此,当头指针与位置的值相等且均指向头结点表示队列空。
3.7 队列主要用于需要排队的场合,以及离散事件的计算机模拟等。
4.串的模式匹配
4.1 朴素的模式匹配算法:基本思想是从主串的第一个字符与模式串的第一个字符比较,若相等,则逐一对字符串进行后续的比较,否则从主串第二个字符与模式串的第一个字符重新比较,直到匹配成功或则失败。
4.2 模式匹配的算法时间复杂度
(1) 假设主串和模式串长度分别为n和m,下表从0开始,假设从主串的第i个位置匹配成功,且在前i趟中都是模式串的第一个字符与主串匹配失败,字符比较次数为i,而第i+1趟成功匹配字符的比较次数为m,总的字符比较次数为i+ m(0<=i<=n-m),若在n-m个位置上匹配成功的概率相同,即
1n−m+1\frac{1}{n-m+1} n−m+11
则,匹配成功时字符的平均比较次数为:
1n−m+1∑i=0n−m(i+m)=n+m2\frac{1}{n-m+1} \displaystyle\sum_{i=0}^{n-m} (i+m) = \frac{n+m}{2} n−m+11i=0∑n−m(i+m)=2n+m
因此,在最好情况下匹配算法的时间复杂度为O(n+m)。
(2)假设最坏情况下,每次匹配不成功都是模式串的最后一个字符不匹配,则前i趟中字符比较了i×m次,第i+1趟也比较了m次,则:
∑i=0n−mm(i+1)n−m+1=12m(n−m+2)\displaystyle\sum_{i=0}^{n-m}\frac{m(i+1)}{n-m+1} = \frac{1}{2}m(n-m+2) i=0∑n−mn−m+1m(i+1)=21m(n−m+2)
因此,在最坏情况下匹配算法的时间复杂度为O(n×m)。
5.矩阵的压缩存储
5.1 n阶对称矩阵,aija_{ij}aij=ajia_{ji}aji,可将n2n^2n2个元素压缩存储到n(n+1)2\frac{n(n+1)}{2}2n(n+1)个元素的存储空间。
采用行为主序存储下三角包括对角线中的元素在数组A中,则A [k]与矩阵元素aija_{ij}aij之间的一一对应关系为:
k={i(i−1)2+ji >= jj(j−1)2+i,i < jk = \begin{cases} \frac{i(i-1)}{2}+j & \text {i >= j} \\ \frac{j(j-1)}{2}+i , & \text{i < j} \end{cases} k={2i(i−1)+j2j(j−1)+i,i >= ji < j