目录
1.栈的基本概念
1.1.栈的定义
栈是只允许在一端进行插入或删除的线性表
栈顶:允许进行插入删除的那一段
栈底:不允许进行插入删除的另一端
进栈顺序:1->2->3->4->5
出栈顺序:5->4->3->2->1(后进先出:LIFO)
1.2.栈的基本操作
initStack(&S); //初始化一个空栈S
stackEmpty(S); //判断栈空
push(&S, x); //进栈
pop(&S, &x); //出栈
getTop(&S, &x); //读栈顶元素
destroyStack(&S); //销毁栈
n个不同元素进栈,出栈的不同序列为
2.顺序栈栈的基本操作
2.1.顺序栈的初始化
- 采用定义一组地址连续的存储单元存放元素(数组)
- 申明一个指针指向当前栈顶元素的位置。栈空时,top的值设置为-1;每加入一个元素,top的值+1,直到栈满,即maxSize - 1(数组的特性,下标从0开始)
#define maxSize 50 //定义栈中的最大元素
typedef struct {
elemType data[maxSize]; //静态数组存放栈中元素
int top; //栈顶指针
}sqStack;
//初始化栈
void initStack(sqStack &S){
S.top = -1; //初始化栈顶指针
}
//判断栈空
bool stackEmpty(sqStack S){
if (S.top == -1) return true; //栈空
else return false; //栈不空
}
void testStack(){
sqStack S;
initStack(S);
//后续操作
}
2.2.进栈操作
//新元素入栈
bool push(sqStack &S, elemType e){
if(S.top == maxSize - 1) return false; //栈满,返回false
else{
//等价于S.data[++S.top] = x;
S.top++; //栈顶指针+1(数组特性)
S.data[S.top] = x; //新元素入栈
return true
}
}
2.3.出栈操作
出栈操作数据实际上还存在于数组中,即内存还存有数据,但是逻辑上删除了
//出栈
bool pop(sqStack &S, elemType &e){
if (S.top == -1) return false; //栈空,返回false
else {
x = S.data[top--]; //先将x从栈顶取出,并带回,再对top进行--操作
return true;
}
}
2.4.读栈顶元素
仅读取的话,不需要对top指针进行修改
//读栈顶元素
bool getTop(sqStack S, elemType &e){
if(S.top == -1) return false; //栈空,返回false
else{
e = S.data[S.top]; //读栈顶元素
return true;
}
}
2.5.共享栈
存元素时,top1指针往下递减,top0指针往上递增
栈满条件:top0 +1 == top1
#define maxSize 10
typedef struct{
elemType data[maxSize];
int top0;
int top1;
}shStack;
void initStack{
S.top0 = -1; //初始化栈顶指针
S.top1 = maxSize;
}
3.王道课后题
bool isLegal(string A) {
int stack = 0;
for (int i = 0; A[i] != '\0'; i++) {
if (A[i] == 'I') stack++;
else stack--;
if (stack < 0) return false;
}
return true;
}
//链表方法
bool isSymmetry(linkList L) {
LNode* fast = L->next, * slow = L->next;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
//p指向后半链表的第一个节点
LNode* p = slow->next, *temp, *s;
//将表分为前半链表和后半链表
slow->next = NULL;
//将s指向后半链表的第一个节点,p指向后半链表的最后一个节点
s = p;
while (p->next) p = p->next;
//通过s和p将后半链表逆置
while (s != p) {
temp = s->next;
s->next = p->next;
p->next = s;
s = temp;
}
//将s指向前半链表的第一个节点
s = L->next;
//依次对比前半链表和逆置后的后半链表
while (p && s) {
if (p->data != s->data) break;
p = p->next;
s = s->next;
}
//如果p在指向NULL之前就跳出循环,则不对称,返回false
if (p) return false;
else return true;
}
//栈
bool isSymmetry(linkList L, int n) {
//创建数组作为栈,并初始化为0
int* arr = (int*)malloc(sizeof(int) * (n / 2));
memset(arr, 0, sizeof(char) * (n / 2));
LNode* p = L->next;
int i;
//遍历前半链表,并将其数据压入栈中
for (i = 0; i < n / 2; i++) {
arr[i] = p->data;
p = p->next;
}
//i退一格,使其指向栈顶元素
i--;
//如果是奇数个,当前p指向的是最中间节点
//需要往后一个节点才是下半个链表的第一个节点
if (n % 2) p = p->next;
//依次判断下半链表元素是否与数组内元素相等
while (p && p->data == arr[i]) {
i--;
p = p->next;
}
//判断是否提前跳出循环
if (p) return false;
else return true;
}
#define maxSize 10
typedef struct {
elemType data[maxSize];
int s1, s2;
}sqStack;
sqStack S;
//入栈
bool push(int i, sqStack S, elemType e) {
//插入的栈号不对
if (i < 1 || i > 2) return false;
//栈满
if (S.s1 + 1 == S.s2) return false;
入栈
if (i == 1) S.data[++S.s1] = e return true;;
else S.data[--S.s2] = e return true;;
}
//出栈
bool pop(int i, sqStack S, elemType e) {
//出栈的栈号不对
if (i < 1 || i > 2) return false;
//栈空
if (i == 1 && S.s1 == -1) return false;
else if (i == 2 && S.s2 == maxSize) return false;
//出栈
if (i == 1) e = S.data[S.s1--] return true;
else e = S.data[S.s2++] return true;
}