对之前学的一些知识点做个总结,比较简略。记录一些容易忘记的点。
抽象数据类型(ADT)
数据结构的基本概念和术语可参考:数据结构基本概念定义(挺详细的)
- 数据类型:是指一组性质相同的值的集合以及定义在此集合上一些操作的总称(data+operation)
- 数据类型 = 原子类型 + 结构类型
– 原子类型,如 int,float,字符串, 是不可分割的基本类型
– 结构类型, 数据结构+操作,可以分割 - 抽象数据类型(ADT):一个数据模型以及定义在该模型上的一组操作
一、列表 ADT
1. 实现列表ADT的两种数据结构:数组(array-based)和链表(linked list)
时间复杂度(效率)
Operation | Array | Linked list |
---|---|---|
Insert | × | ✔ O(n) |
Remove | × | ✔ O(n) |
Find | 一样 O(n) | 一样 O(n) |
FindKth | ✔ O(1) | × O(n) |
空间复杂度: Linked list需要记录所有node的地址,所以数组所需要的space更少
linked list更适合实现链表的操作。因为数组的长度是不能改的。
2. 链表的结构
typedef struct node{
double data;
struct node* next;
}Node;
3. 操作
bool IsEmpty(Node* head)
- 判断head是否为null
Node* InsertNode(Node** phead, int index, double x)
- 在最前面insert:创建值为x的node,next指向head,head指向next
- 在其他位置insert:找到index位置上的node,保存这个node的next,…
int FindNode(Node* head, double x)
- 返回x都一次出现的地方:遍历所有直到找到为止
Int DeleteNode(Node** phead, double x)
- 删除最前面的;删除中间或者后面的
- 删除后释放空间(free)
void DisplayList(Node* head)
- 遍历完然后一个个print
void DestroyList(Node* heas)
- deletes all the nodes in the list
- frees the memory allocated to the nodes
二、栈 ADT
是一种特殊的List ADT
1. 插入和删除都在同一个地方(在top),First In Last Out
2. 栈的应用
- Expression evaluation (prefix,infix,postfix)
- 回溯,返回上一级(搜索,查找路径等)
- 内存管理(memory management)
3. 实现栈ADT的两种数据结构:数组(array-based)和链表(linked list)
Operation | Array | Linked list |
---|---|---|
Push | O(1) | O(1) |
Pop | O(1) | O(1) |
Top | O(1) | O(1) |
更适合用数组来实现,因为数组是个物理结构,可以直接找到。或者用反向的链表,rear的指针指向最后一个node。
4. 栈的结构
typedef struct stack{
double* values;
int top;
int maxTop;
}Stack;
5. 操作
假设 maxTop = size - 1
Bool CreateStack(Stack *stack, int size)
- 创建一个新的stack
bool IsEmpty(Stack* stack);
- Top为-1
bool IsFull(stack* stack);
- Top = maxTop
bool Top(Stack* stack, double* x);
- 返回stack.values[stack.top]
bool Push(Stack* stack, double x);
- 看看有没有满
- 没满的话加到stack.values[stack.top+1]
bool Pop(Stack* stack, double* x);
- 看看空不空
- 不空的话删除stack.values[stack.top],top -= 1
void DisplayStack(Stack* stack);
- 遍历stack中的values
void DestroyStack(Stack* stack);
- free values
- free stack
三、队列 ADT
是一种特殊的List ADT
1. 在最后面(rear)插入,在最前面(front)删除都在同一个地方(在top),First In First Out
2. 队列的应用
- 打印
- 网页爬取
- 系统缓冲区(system buffer)
3. 队列的结构
typedef struct queue{
double* values;
int front;
int rear;
int counter; // 队列里一共有几个元素
}Stack;
4. A circular array
首尾相连的array,有一个固定的长度。
5. 操作
bool CreateQueue(Queue *queue, int size);
- size,定义的数组长度
bool IsEmpty(Queue* queue);
- front和rear重合,counter == 0
bool IsFull(Queue* queue);
- front和rear重合,counter == maxSize
bool Enqueue(Queue* queue, double x);
- 看看队列满不满
- 在rear插入,(rear的位置+1)% size
bool Dequeue(Queue* queue, double* x);
- 看看队列空不空
- 在front删除,(front的位置+1)% size
void DisplayQueue(Queue* queue);
- 从头(front)开始遍历,到size再到1
void DestroyQueue(Queue** pqueue);
- free(values)
- free(queue)
四. 优先级队列(priority queue)
1. 基本思想
- enqueue:insert后进行堆排序(上小下大) O(logn)
- dequeue:最前面是min O(logn)