栈(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),而链表则是一种更为通用的线性表结构,允许更为灵活的数据组织和访问。
虽然它们都可以用数组或链表来实现,但栈关注的是“栈顶”操作,而链表关注的是任意位置节点间的链接关系。