栈(Stack):
- 栈是一种特殊的线性表,遵循“后进先出”(Last In First Out, LIFO)原则。
- 栈通常用数组或链表来实现,但重点在于其操作的限制而非底层数据结构。无论使用顺序栈(基于数组)还是链式栈(基于链表),栈的基本操作包括 push(入栈,将元素添加到栈顶)、pop(出栈,移除并返回栈顶元素)和 peek(查看栈顶元素但不移除)。
- 数组实现的栈空间是预分配和静态的,若超出栈的容量,不进行动态扩容,可能会导致溢出。链表实现的栈则可以动态扩展,不受固定大小限制。
#include <iostream>
#include <stack>
using namespace std;
int main() {
stack<int> myStack;// 创建一个整数类型的栈
int n;
cin>>n;
cout << "Pushing elements onto the stack...\n";
for (int i = 1; i <= n; ++i) {
myStack.push(i);
}
// 输出栈的大小
cout << "Size of the stack: " << myStack.size() << endl;
// 访问栈顶元素但不删除(peek操作)
cout << "Top element on the stack is: " << myStack.top() << endl;
// 出栈(删除并返回栈顶元素)操作
cout << "Popping elements from the stack...\n";
while (!myStack.empty()) {
cout << "Popped element: " << myStack.top() << endl;
myStack.pop();
}
// 判断栈是否为空
cout << "Is the stack empty? " << (myStack.empty() ? "Yes" : "No") << endl;
return 0;
}
定义了一个整数类型的栈,并依次将1至n压入栈中。然后显示栈的大小,访问并打印栈顶元素但不移除。接下来,我们将栈顶元素逐一出栈并打印,直至栈为空。最后检查栈是否为空并输出结果。
链表(Linked List):
- 链表是一种动态数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。
- 链表分为单链表、双链表和循环链表等多种变体,它们不限于栈的操作模式,而是可以进行任意位置的插入和删除操作。
- 链表的优势在于其灵活的内存分配,可以充分利用不连续的内存空间,并且在大量插入和删除的情况下效率相对较高,但访问速度不如数组随机访问快,每次访问都需要从头节点开始逐个遍历。
- 链表并不直接对应栈的数据结构,但可以作为栈的底层实现之一。
#include <iostream>
struct ListNode {// 定义链表节点结构体
int value; // 节点存储的数据
ListNode* next; // 指向下一个节点的指针
};
ListNode* createNode(int val) {// 创建新节点
ListNode* newNode = new ListNode();
if (newNode) {
newNode->value = val;
newNode->next = nullptr;
}
return newNode;
}
// 在链表尾部插入新节点
void insertAtEnd(ListNode** head, int val) {
ListNode* newNode = createNode(val);
if (*head == nullptr) {
*head = newNode;
}
else {
ListNode* temp = *head;
while (temp->next != nullptr) {
temp = temp->next;
}
temp->next = newNode;
}
}
void displayList(ListNode* head) {// 显示链表元素
ListNode* current = head;
while (current != nullptr) {
std::cout << current->value << " -> ";
current = current->next;
}
std::cout << "nullptr" << std::endl;
}
int main() {
ListNode* myList = nullptr; // 初始化为空链表
insertAtEnd(&myList, 1);// 插入几个元素
insertAtEnd(&myList, 2);
insertAtEnd(&myList, 3);
displayList(myList); // 显示链表内容
// 注意:这里省略了释放链表节点内存的代码,实际项目中应确保正确释放内存
return 0;
}
栈是约束性的数据结构,强调操作的有序性(LIFO),而链表则是一种更为通用的线性表结构,允许更为灵活的数据组织和访问。
虽然它们都可以用数组或链表来实现,但栈关注的是“栈顶”操作,而链表关注的是任意位置节点间的链接关系。