Skip to content

Commit 2c37144

Browse files
committed
DS 3
1 parent 1872fbe commit 2c37144

2 files changed

Lines changed: 196 additions & 14 deletions

File tree

docs/CS/data_structure/data_structure.md

Lines changed: 195 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
## ch1.算法评价
66

7-
* 算法有以下五个重要特性
8-
1. 输入算法在执行前需要外界提供0个或多个输入数据。
9-
2. 输出算法在执行后至少产生一个输出数据。
10-
3. 有穷性算法必须在执行有限步骤后终止。
11-
4. 确定性算法的每一步都有确定的含义,不能有歧义。
12-
5. 可行性算法的每一步都能通过有限的时间和空间来完成。
13-
* 时间复杂度比较
7+
* 算法有以下五个重要特性:
8+
1. 输入:算法在执行前需要外界提供0个或多个输入数据。
9+
2. 输出:算法在执行后至少产生一个输出数据。
10+
3. 有穷性:算法必须在执行有限步骤后终止。
11+
4. 确定性:算法的每一步都有确定的含义,不能有歧义。
12+
5. 可行性:算法的每一步都能通过有限的时间和空间来完成。
13+
* 时间复杂度比较:
1414
* $$ O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n) $$
1515

1616
* 题目
@@ -27,18 +27,201 @@
2727
时间复杂度为 O(n),因为外层循环执行 logn 次,内层循环执行 i 次,i 依次为 1,2,4,...,n/2,因此总的执行次数为 1 + 2 + 4 + ... + n/2 = n - 1 = O(n)。
2828

2929

30-
31-
32-
3330
## ch2.线性表
3431

35-
36-
32+
### 2.1 定义与操作
33+
* 定义:具有相同数据类型的n个数据元素的优先序列
34+
35+
* 基本操作:
36+
1. InitList(&L)
37+
2. Length(L)
38+
3. LocateElem(L, e)
39+
4. GetElem(L, i)
40+
5. ListInsert(&L, i, e)
41+
6. ListDelete(&L, i, e)
42+
7. PrintList(L)
43+
8. Empty(L)
44+
9. DestroyList(&L)
45+
### 2.2 顺序表
46+
* 定义:一组地址连续的存储单元依次存储线性表中的数据元素,使得逻辑相邻等于物理相邻。
47+
* 优缺点
48+
* 优点:存储密度高,随机存取,访问速度快。
49+
* 缺点:插入和删除操作需要移动大量元素,空间利用率不高。
50+
* 基本操作:
51+
1. InitList(&L)
52+
* 初始化顺序表长度,根据动态与否分配一段连续的存储空间。
53+
2. ListInsert(&L, i, e)
54+
* 插入元素e到顺序表L的第i个位置,i从1开始计数。最好最坏平均分别为 O(1), O(n), O(n)。
55+
3. ListDelete(&L, i, e)
56+
* 删除顺序表L的第i个位置的元素,并将其值赋给e。最好最坏平均分别为 O(1), O(n), O(n)。
57+
4. LocateElem(L, e)
58+
* 查找顺序表L中值为e的元素,返回其位置。最好最坏平均分别为 O(1), O(n), O(n)。
59+
5. GetElem(L, i)
60+
* 获取顺序表L的第i个位置的元素。自然为 O(1)。
61+
### 2.3 链表
62+
* 定义:使用data|next结构存储线性表中的数据元素,data存储数据元素,next存储下一个元素的地址。
63+
```
64+
typedef struct LNode {
65+
ElemType data;
66+
struct LNode *next;
67+
} LNode, *LinkList;
68+
```
69+
* 特性:非随机存取,离散,遍历,可带头结点(头结点不存储数据,可存表长)。
70+
* 解决问题:插入删除O(1),头结点使得第一个点不特殊(不必头指针处理),便于处理。
71+
* 基本操作:
72+
1. InitList(&L)
73+
```
74+
L = (LNode *)malloc(sizeof(LNode));
75+
L->next = NULL;
76+
return true;
77+
```
78+
2. Length(L)
79+
3. GetElem(L, i)
80+
4. LocateElem(L, e)
81+
5. ListInsert(&L, i, e)
82+
* 前插法需要找到第i-1个结点p,而后插法可以直接通过第i个结点p执行插入
83+
6. ListDelete(&L, i, e)
84+
7. List_HeadInsert(&L, e)
85+
8. List_TailInsert(&L, e)
86+
* 双向链表
87+
```
88+
typedef struct DNode {
89+
ElemType data;
90+
struct DNode *prior, *next;
91+
} DNode, *DLinkList;
92+
```
93+
* 操作:插入删除
94+
* 循环链表
95+
* 单向循环链表:尾结点的next指向头结点
96+
* 双向循环链表:头结点的prior指向尾结点,尾结点的next指向头结点
97+
* 静态链表
98+
* 用数组模拟链表,数组下标作为指针使用
99+
* 适用于结点频繁插入删除的场景
100+
* 需要一个备用链表来存储空闲结点
101+
```
102+
typedef struct {
103+
ElemType data;
104+
int next; // 下一个元素的数组下标
105+
} SLinkList[MAXSIZE];
106+
```
107+
* next == -1 作为结束标志
37108
38109
## ch3.栈、队列和数组
39110
111+
### 3.1 栈
112+
* 定义: LIFO(后进先出)数据结构
113+
* 特性: 只能在栈顶进行插入和删除操作
114+
* 基本操作:
115+
1. InitStack(&S)
116+
2. StackEmpty(S)
117+
3. Push(&S, e)
118+
4. Pop(&S, &e)
119+
5. GetTop(S, &e)
120+
6. DestroyStack(&S)
121+
* 特性: $n$ 个不同元素进栈时,出栈元素的不同排列数为 $C_n = \dfrac{1}{n+1} \binom{2n}{n}$(卡特兰数)
122+
123+
#### 3.1.1 栈的顺序存储
124+
* 定义:使用一段地址连续的存储单元依次存储栈中的数据元素,top指向栈顶元素,初始值为-1.
125+
````
126+
typedef struct {
127+
ElemType data[MAXSIZE];
128+
int top; // 栈顶指针
129+
} SqStack;
130+
````
131+
* 操作:
132+
1. InitStack(&S)
133+
2. StackEmpty(S)
134+
3. Push(&S, e)
135+
4. Pop(&S, &e)
136+
5. GetTop(S, &e)
137+
138+
* 共享栈
139+
````
140+
0 MAXSIZE-1
141+
| | | |
142+
bottom 0 top0 top1 bottom 1
143+
````
144+
* top0从左向右增长,top1从右向左增长
145+
* top0 + 1 == top1 时栈满
146+
* top0 == -1 时栈0空,top1 == MAXSIZE 时栈1空
147+
148+
* 链式栈
149+
* 定义:使用链表存储栈中的数据元素,LHead指向栈顶元素。
150+
````
151+
typedef struct LNode {
152+
ElemType data;
153+
struct LNode *next;
154+
} LNode, *LinkStack;
155+
````
156+
### 3.2 队列
157+
* 定义: FIFO(先进先出)数据结构
158+
````
159+
typedef struct {
160+
ElemType data[MAXSIZE];
161+
int front, rear; // 队头和队尾指针
162+
} SqQueue;
163+
````
164+
* 特性: 只能在队头(Front)进行删除操作,在队尾(Rear)进行插入操作
165+
* 基本操作:
166+
1. InitQueue(&Q)
167+
2. QueueEmpty(Q)
168+
3. EnQueue(&Q, e)
169+
4. DeQueue(&Q, &e)
170+
5. GetHead(Q, &e)
171+
6. DestroyQueue(&Q)
172+
* 问题:
173+
* 队列满: rear == MAXSIZE 产生"假队列溢出"
174+
* 队列空: front == rear
175+
* 循环队列
176+
* 初始时: front == rear == 0
177+
* 队首指针进1: front = (front + 1) % MAXSIZE
178+
* 队尾指针进1: rear = (rear + 1) % MAXSIZE
179+
* 队列长度: (rear - front + MAXSIZE) % MAXSIZE
180+
* 出队入队:指针顺时针加一
181+
* 队列空: front == rear
182+
* 三种处理方式:
183+
* 牺牲一个单元区分队空和满,入队时少用一个队列单元
184+
* 队满: (rear + 1) % MAXSIZE == front
185+
* 队空: front == rear
186+
* 元素个数: (rear - front + MAXSIZE) % MAXSIZE
187+
* 增加size变量记录队列长度
188+
* 队满: size == MAXSIZE
189+
* 队空: size == 0
190+
* 元素个数: size
191+
* 新加tag区分队空和满
192+
* 队满: 插入导致rear == front 置tag == 1
193+
* 队空: 删除导致front == rear 置tag == 0
194+
* 元素个数: (rear - front + MAXSIZE) % MAXSIZE
195+
![循环队列](https://eclipseyue-1323281044.cos.ap-nanjing.myqcloud.com/pic/REqueue.jpg)
196+
* 队列的链式存储
197+
* 定义:使用链表存储队列中的数据元素,QHead指向队头元素,QTail指向队尾元素。
198+
````
199+
typedef struct LinkNode {
200+
ElemType data;
201+
struct LinkNode *next;
202+
} LinkNode;
203+
typedef struct {
204+
LinkNode *front, *rear; // 队头和队尾指针
205+
} LinkQueue;
206+
````
207+
* 不带头结点时,front == rear == NULL,则队列空。但是常用头结点单链表
208+
209+
210+
* 双端队列
211+
* 定义:可以在队头和队尾进行插入和删除操作
212+
* 输入/输出受限的队列:只能在一端进行插入操作,或只能另一端进行删除操作
213+
* !!!这里需要做一下题
214+
215+
216+
### 3.3 应用
217+
记录几道题:
218+
!!!做题
219+
### 3.4 数组和特殊矩阵
220+
!!!做题
221+
40222
## ch4.串
41223
224+
42225
## ch5.树与二叉树
43226
44227
## ch6.图

docs/index.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
# 你好
1+
行百步者半九十
22

33
这里是月全食的个人主页
44

5-
随便写写记录一下一些内容

0 commit comments

Comments
 (0)