1.1 栈和基本运算
栈:只允许在一端进行插入和删除的线性表
栈顶:允许插入和删除的一端
栈底:不允许……
s_0是栈底节点,s_{n-1}是栈顶结构
特性:先进后出(后进先出)LIFO(Last In First Out)
栈顶指针:一般用一个指针top来指向数组存放的位置。
栈的实现
#include<iostream>
using namespace std;
typedef int data;
const int MAXN = 1000;
struct static_stack
{
data ptr[MAXN];
int num = 0;
int push(data a)
{
if(num == MAXN)
{
return 0;//满
}
ptr[num++] = a;
return 1;
}
int pop()
{
if(num == 0)
return 0;
num--;
return 1;
}
};
struct stack
{
data* ptr;
int num;
int cap;
stack(int n = 100)
{
ptr = new data[n];
for(int i = 0; i < n; i++)
ptr[i] = 0;
cap = n;
num = 0;
}
int resize(int n)
{
data*temp = new data[n];
int times;
if(n <= cap) times = n;
else times = cap;
for(int i = 0; i < times; i++)
{
temp[i] = ptr[i];
}
delete[] ptr;
ptr = temp;
}
int push(data a)
{
if(num == MAXN)
{
return 0;//满
}
ptr[num++] = a;
return 1;
}
int pop()
{
if(num == 0)
return 0;
num--;
return 1;
}
};
1.2 队列和基本运算
队列:只允许在一端插入,在另一端删除的线性表
队首:允许删除的一端
队尾:允许插入的一端
入队:队列的插入
出队:队列的删除
先进先出表 FIFO(Fisrt In First Out)
不难发现这个十分类似于栈实现
#include<iostream>
using namespace std;
typedef int data;
const int MAXN = 1000;
struct queue
{
data ptr[MAXN];
int head;
int tail;
queue()
{
for(int i = 0; i < MAXN; i++)
ptr[i] = 0;
head = -1;
tail = -1;
}
int en_queue(data a)
{
if(tail == MAXN -1)
return 0;
ptr[tail++] = a;
return 1;
}
int de_queue()
{
if(head == tail)
return 0;
head++;
return 1;
}
};
1.3 环形队列
但是我们在使用这种队列的时候会有一些惊讶的发现:当尾部入列满,且头部也有一部分出列的时候(也就是数组还有空位的时候),我们无法再插入新的元素,就会造成空间上的浪费
于是我们可以使用环形队列:
尾部插满的时候,继续循环插入头部,如何实现呢?利用%运算
但是出现一个新的问题,当tail == head的时候,到底是队满还是队空呢?
有两种解决方法
第一种是增加一个标识符flag来判断,倘若是入队之后tail == head就有flag = 1,反之为0,但是这种处理方法就会导致程序增加多一个判断操作和数据操作
第二种的话我们可以让tail和head在插入的时候“永远不相等”,先让tail++,若tail == head,说明栈满,再tail–,而当tail == head 的时候只能是队空,保证了一一对应(通过减少一个空间的储存来避免这种判断操作)
int cir_enqueue(data d)
{
tail = (tail + 1) % MAXN;
if(tail == head)
{
if(tail)
tail--;
else
tail = MAXN - 1;
return 0;//插入错误
}
ptr[tail] = d;
return 1;
}
int cir_dequeue()
{
if(head == tail)
return 0;//栈空
head = (head + 1) % MAXN;
return 1;
}
1.4 双向队列
便是让两端都可以进行插入或删除
可以产生许多变体:俩端可插入但只在一端删除……环形双线队列
1.5 栈的应用
课后作业
就是普通的栈考虑上尾端,然后特殊判断一下用栈1还是栈2
#include<iostream>
using namespace std;
typedef int data;
struct shared_stack
{
data* head;
int cap;
int head_num;
int end_num;
shared_stack(int n)
{
head = new data[n];
cap = n;
end_num = 0;
head_num = 0;
}
int push(data d, int index)
{
if(end_num + head_num == cap)
return 0; //满
switch (index)
{
case 1:
head[head_num++] = d;
break;
default:
head[cap - end_num - 1] = d;
end_num++;
break;
}
return 1;
}
int pop(int index)
{
if(1 == index)
{
if(head_num <= 0)
return 0;
head_num--;
}
else
{
if(end_num <= 0)
return 0;
end_num--;
}
return 1;
}
};