链栈和顺序栈,基本操作相同,唯一的区别在于,顺序栈是一次直接分配好空间,链式栈根据插入数据的多少分配空间,不存在浪费和溢出…
代码实现
#include <iostream>
#include <Windows.h>
#include <stdio.h>
#define MAX_SIZE 100 // 栈可以最多存储的数据个数
// 链栈的定义
typedef int ELEM; // 数据的类型, 可以是其他任意类型
typedef struct _Node {
ELEM date; // 保存数据
struct _Node* next; // 保存下一次存储数据的地址,实现连接
}Node;
typedef struct _Stack {
int length; //个数
Node* base; //栈底
Node* top; //栈顶
}Stack;
// 初始化栈
void initStack(Stack& s) {
s.base = s.top = NULL;
s.length = 0;
}
// 栈空
bool isEmpty(const Stack& s) {
if(s.base == NULL) return true;
return false;
}
//栈满, 理论上可以无限大, 但是还是设置一个上限好, 比如10w, 100w, 这个数值根据项目需要设计
bool isFull(const Stack& s) {
if(s.length >= MAX_SIZE) return true;
return false;
}
// 入栈
bool pushStack(Stack& s, ELEM& e) {
if(isFull(s)) return false; //栈已满
Node* p = new Node;
if(!p) return false; // 分配空间失败
p->date = e;
p->next = NULL;
//1 空栈
if(isEmpty(s)) {
s.base = s.top = p;
} else { // 2. 已有元素存入
s.top->next = p;
s.top = p;
}
s.length++;
return true;
}
// 出栈
bool popStack(Stack& s, ELEM& e) {
if(isEmpty(s)) return false; //空栈不能出栈元素
e = s.top->date;
Node* p = s.base;
while(p->next != s.top) { // p->next == s.top时,退出循环
p = p->next;
}
// 释放出栈元素
delete s.top;
s.top = p; //s.top指向新的出栈元素,即本次出栈元素的上一个
s.length--; //长度-1
return true;
}
// 获取长度
int length(Stack& s) {
return s.length;
}
// 获取出栈元素,不出栈
bool getElem(Stack& s, ELEM& e) {
if(s.base == NULL) return false; //空栈,不存在元素
e = s.top->date;
return true;
}
// 栈的销毁
void destroy(Stack& s) {
Node* p = s.base;
while(p) {
s.base = p->next;
delete p;
p = s.base;
}
s.base = s.top = NULL;
s.length = 0;
}
int main(void) {
Stack s;
ELEM e;
// 初始化栈
initStack(s);
// 入栈5个元素
for(int i=0; i<5; i++) {
e = i+1;
if(pushStack(s, e)) {
printf("入栈成功,入栈元素为:%d\n", e);
} else {
printf("入栈失败\n");
}
}
// 获取长度和栈顶元素
printf("栈的长度为:%d\n", length(s));
if(getElem(s, e)) {
printf("获取成功,元素为:%d\n\n", e);
} else {
printf("获取失败\n\n");
}
// 尝试销毁栈后, 出栈是否有误
// destroy(s);
// 出栈3个元素
int i = 3;
while(i--) {
if(popStack(s, e)) {
printf("出栈成功,出栈元素为:%d\n", e);
} else {
printf("出栈失败\n");
}
}
system("pause");
return 0;
}