更新数据结构第二章

This commit is contained in:
Alice-and-Bob
2020-07-07 21:55:26 +08:00
parent a86b2a9539
commit a11f0e8b45
6 changed files with 336 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
# 栈的顺序存储
## 顺序存储数据结构定义
```cpp
#define MaxSize 50
typedef struct
{
Elemtype data[MaxSize];
int top;
}SqStack;
```
## 顺序栈的基本运算
### 1. 初始化
```cpp
void InitStack(SqStack &S){
S.top = -1;
}
```
### 2. 判定空
```cpp
bool StackEmpty(SqStack &S){
if(S.top == -1){
return true;
}
else{
return false;
}
}
```
### 3. 进栈
```cpp
bool Push(SqStack &S, Elemtype x){
if(S.top == MaxSize-1){
return false;
}
S.data[++S.top] = x;
return true;
}
```
### 4. 出栈
```cpp
bool Pop(Sqstack &S, Elemtype &x){
if(S.top == -1){
return false;
}
x = S.data[S.top--];
return true;
}
```
### 5. 读栈顶元素
```cpp
bool GetTop(Sqstack &S, Elemtype &x){
if(S.top == -1){
return false;
}
x = S.data[S.top];
return true;
}
```
# 栈的链式存储结构
## 数据结构
```cpp
typedef struct Linknode{
Elemtype data;
struct Linknode *next;
}*LiStack;
```

View File

@@ -0,0 +1,110 @@
# 队列的顺序存储
## 数据结构
```cpp
#define MaxSize 50;
typedef struct{
Elemtype data[MaxSize];
int front, rear;
}SqQueue;
```
* 缺点:对连续空间的利用率差,容易出现假溢出现象
## 改进:循环队列
### 队列指针的变化
* 初始时:`Q.front = Q.rear = 0`
* 队首指针进1:`Q.front = (Q.front+1)%MaxSize`
* 队尾指针进1:`Q.rear = (Q.rear+1)%MaxSize`
* 队列长度:`(Q.rear+MaxSize-Q.front)%MaxSize`
* 出队入队时:指针按顺时针方向进1
### 区分对空队满
1. 牺牲一个空单元
* 队满条件:`(Q.rear+1)%MaxSize==Q.front`
* 队空条件:`Q.front=Q.rear`
* 队列元素个数:`(Q.rear-Q.front+MaxSize)%MaxSize`
2. 类型中增设表示元素个数的数据成员
3. 类型中增设tag数据成员
### 循环队列的基本操作(采用牺牲空单元法)
#### 1. 初始化
```cpp
void InitQueue(SqQueue &Q){
Q.front = Q.rear = 0;
}
```
#### 2. 判空
```cpp
bool isEmpty(SqQueue &Q){
if(Q.rear = Q.front){
return true;
}
else{
return false;
}
}
```
#### 3. 出队
```cpp
bool DeQueue(SqQueue &Q, Elemtype &x){
if(Q.front = Q.rear) return false;
x = Q.data[Q.front];
Q.front = (Q.front+1) % MaxSize;
}
```
#### 4. 入队
```cpp
bool EnQueue(SqQueue &Q, Elemtype x){
if((Q.rear+1)%MaxSize==Q.front) return false;
Q.data[Q.rear]= x;
Q.rear = (Q.rear+1) % MaxSize;
return true;
}
```
# 队列的链式存储结构
## 数据结构
```cpp
typedef struct{
Elemtype data;
struct LinkNode *next;
}LinkNode;
typedef struct{
LinkNode *front, *rear;
}LinkQueue;
```
## 基本操作
### 1. 初始化
```cpp
void InitQueue(LinkQueue &Q){
Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
Q.front->next = NULL;
}
```
### 2. 判空
```cpp
bool IsEmpty(LinkQueue &Q){
if(Q.front == Q.rear) return true;
else return false;
}
```
### 3. 入队
```cpp
bool EnQueue(LinkQueue &Q, Elemtype x){
LinkNode *s = (LinkNode *) malloc(sizeof(LinkNode));
s->data = x;
s->next = NULL;
(Q.rear)->next = s;
Q.rear = s;
}
```
### 4. 出队
```cpp
bool DeQueue(LinkQueue &Q, Elemtype x){
if(Q.front == Q.rear) return false;
LinkNode *p = Q.front->next;
x = p->data;
if(Q.front == Q.rear){
Q.rear = Q.front;
}
free(p);
return true;
}
```

View File

@@ -0,0 +1,158 @@
/***
* @Author: Alice-and-Bob
* @Date: 2020-04-17 22:54:59
* @LastEditTime: 2020-07-05 15:59:35
* @LastEditors: Alice-and-Bob
* @Description:
* @*******************************************
* @* 全世界程序员,联合起来! *
* @* Programmers of all lands, Unite! *
* @* программист всех стран, соединяйтесь! *
* @*******************************************
*/
21、
//1、遍历单链表统计元素个数为n;从头指针所指向的节点开始从0遍历到n-k的位置;
//2、从list指向的第一个节点开始遍历链表,同时用一个变量n记录元素个数;获得元素个数n后,n与k比较,若n<k则说明k越界,返回0;否则,
//倒数k个元素即是正数n-k个元素(从0开始对节点编号),从0号节点开始遍历到n-k个节点,并输出该节点的data域,返回1
//3、
int
foo(Linklist &list)
{
int n = 0;
LNode *p = list;
while (p != NULL)
{
n++;
}
if (n < k)
{
return 0;
}
else
{
p = list;
for (int i = 0; i < n - k; i++)
{
p = p->next;
}
cout << p->data;
return 1;
}
}
22、
//1、求链表长度m,n。对pq进行对齐,使其到链表尾的距离相等;同时前进,当p=q时,即取得位置
typedef struct Node
{
char data;
struct Node *next;
} SNode;
int listlen(SNode *head)
{
int len = 0;
while (head->next != NULL)
{
len++;
head = head->next;
}
return len;
}
SNode *find_addr(SNode *str1, SNode *str2)
{
int m, n;
SNode *p = str1, *q = str2;
m = listlen(str1);
n = listlen(str2);
if (m > n)
{
for (int i = 0; i < m - n + 1; i++)
{
p = p->next;
}
}
else
{
for (int i = 0; i < n - m + 1; i++)
{
q = q->next;
}
}
while (p->next != NULL && q->next != p->next)
{
p = p->next;
q = q->next;
}
return p - next;
} //O(len1+len2)
23、
//1、新建一个大小为n+1的辅助数组q默认值全为0,从头开始扫描源链表,对某个链表元素的data,访问q[|data|],如果为0,则改为1;如果为1,则删除当前链表节点
typedef struct Node
{
int data;
struct Node *next;
} SNode;
void func(SNode *p, int n)
{
int q[n + 1] = {0};
SNode t;
while (p->next != NULL)
{
if (q[abs(p->next->data)] == 0)
{
q[abs(p->next->data)] = 1;
}
else
{
t = p->next;
p->next = p->next->next;
free(t);
}
p = p->next;
} //处理了前m-1个
//对于最后一个链表元素
if (q[abs(p->data)] == 1)
free(p);
} //Ot(m),Os(n)
25、
//1、找到链表中间节点,后半段原地逆序,再按要求从头和中间位置每次去一个节点连接成新链表
typedef struct node
{
int data;
struct node *next;
} Node;
void func(NODE *h)
{
Node *p, *q, *r, *s;
p=h;q=h;
while(q->next!=NULL){
p=p->next;
q=q->next;
if(q->next!=NULL) q=q->next;
}//p在链表中间位置
q=p->next;
p->next=NULL;
//断开前后两段链表连接
while(q!=NULL){
r=q->next;
q->next=p->next;
p->next=q;
q=r;
}
//后半段逆序
while(q!=NULL){
r=q->next;
q->next=s->next;
s->next=q;
s=q->next;
q=r;
}
//按要求重组
}//O(n)