链式栈和线性栈
1. 线性栈(顺序栈)
结构定义:
#include <iostream>
using namespace std;#define MAX_SIZE 100 // 预定义最大容量// 线性栈结构体
typedef struct {int* data; // 存储数据的数组int top; // 栈顶指针(初始化为-1)int capacity; // 当前栈的最大容量
} SeqStack;// 初始化栈
void InitSeqStack(SeqStack& S) {S.data = new int[MAX_SIZE];S.top = -1;S.capacity = MAX_SIZE;
}// 销毁栈(释放内存)
void DestroySeqStack(SeqStack& S) {delete[] S.data;S.top = -1;S.capacity = 0;
}
常见操作:
// 入栈
bool PushSeqStack(SeqStack& S, int x) {if (S.top == S.capacity - 1) {// 栈满时自动扩容(示例中扩容为原大小的2倍)int newCapacity = S.capacity * 2;int* newData = new int[newCapacity];for (int i = 0; i <= S.top; i++) {newData[i] = S.data[i];}delete[] S.data;S.data = newData;S.capacity = newCapacity;}S.data[++S.top] = x; // 栈顶指针先增1,再赋值return true;
}// 出栈
bool PopSeqStack(SeqStack& S, int& x) {if (S.top == -1) {cout << "栈空,无法出栈!" << endl;return false;}x = S.data[S.top--]; // 先取栈顶元素,再减1return true;
}// 取栈顶元素
bool GetTopSeqStack(SeqStack& S, int& x) {if (S.top == -1) return false;x = S.data[S.top];return true;
}// 判空
bool IsEmptySeqStack(SeqStack& S) {return S.top == -1;
}
2. 链栈
结构定义:
#include <iostream>
using namespace std;// 链栈节点结构体
typedef struct LinkNode {int data;struct LinkNode* next;
} LinkNode;// 链栈结构体(通过头指针管理)
typedef struct {LinkNode* top; // 栈顶指针
} LinkStack;// 初始化栈
void InitLinkStack(LinkStack& S) {S.top = NULL; // 初始化为空栈
}// 销毁栈(释放所有节点)
void DestroyLinkStack(LinkStack& S) {LinkNode* p = S.top;while (p) {LinkNode* tmp = p;p = p->next;delete tmp;}S.top = NULL;
}
常见操作:
// 入栈
bool PushLinkStack(LinkStack& S, int x) {LinkNode* newNode = new LinkNode;if (!newNode) {cout << "内存分配失败!" << endl;return false;}newNode->data = x;newNode->next = S.top; // 新节点指向原栈顶S.top = newNode; // 更新栈顶指针return true;
}// 出栈
bool PopLinkStack(LinkStack& S, int& x) {if (!S.top) {cout << "栈空,无法出栈!" << endl;return false;}LinkNode* tmp = S.top; // 保存栈顶节点x = tmp->data; // 取栈顶数据S.top = S.top->next; // 更新栈顶指针delete tmp; // 释放旧栈顶节点return true;
}// 取栈顶元素
bool GetTopLinkStack(LinkStack& S, int& x) {if (!S.top) return false;x = S.top->data;return true;
}// 判空
bool IsEmptyLinkStack(LinkStack& S) {return S.top == NULL;
}
3. 对比总结
特性 | 线性栈(顺序栈) | 链栈 |
---|---|---|
存储结构 | 数组(连续内存) | 链表(离散内存) |
内存分配 | 静态预分配(可动态扩容) | 动态分配节点(按需增减) |
入栈操作 | data[++top] = x (可能需扩容) | 创建新节点并调整指针 |
出栈操作 | top-- (无需释放内存) | 释放节点内存 |
空间复杂度 | O(n)O(n)(预分配空间) | O(n)O(n)(每个节点含指针域) |
内存管理 | 整体一次性分配/释放 | 逐个节点分配/释放 |
适用场景 | 数据量固定或可预估 | 数据量动态变化,内存需求不确定 |
通过代码对比可以清晰看出:
- 线性栈适合确定容量或需要快速随机访问的场景(如函数调用栈)。
- 链栈适合动态数据量或需要灵活内存管理的场景(如递归算法)。