栈
一、栈(stack)
1、栈的特点
栈(Stack)是一种线性存储结构,它具有如下特点:
【注意】:
(1)栈中的数据元素遵守”先进后出”(First In Last Out)的原则,简称FILO结构。
(2)限定只能在栈顶进行插入和删除操作。
栈在计算机中应用相当广泛,包括递归的调用和返回、二叉树和森林的遍历、调用子程序及从子程序返回、表达式的转换和求值、CPU的中断处理等等。
2、栈的相关概念
(1)栈顶与栈底:允许元素插入与删除的一端称为栈顶,另一端称为栈底。
(2)压栈:栈的插入操作,叫做进栈,也称压栈、入栈。
(3)弹栈:栈的删除操作,也叫做出栈。
如下是栈的操作:
- 初始状态:
- 开始 a 入栈:
- 开始 b 入栈:
- 开始 c 入栈:
- 弹出栈顶元素:
- 继续弹出栈顶元素:
请看下图:
只能在栈顶进行入栈、出栈操作,其中表头对应的是栈底,表尾对应的栈顶。
内存中的堆栈与数据结构堆栈的区别?
内存中的堆栈是真实存在的物理区,数据结构中的堆栈是抽象的数据存储结构。
为什么用栈来保存临时变量?
其实,也不一定要用栈来保存临时变量,只不过如果这个函数调用符合“后进先出”的特性,就会立马想到用栈这种数据结构来实现。
从调用函数进入到被调用函数,对于数据来说,变化的是作用域。所以在根本上只要能保证每进入一个新的函数,都是一个新的作用域就可以。而要实现这个,用栈就非常方便。在进入被调用函数的时候,分配一段栈空间给这个函数的变量,在函数结束的时候,将栈顶复位,正好就回到调用函数的作用域内。
以下是自己手写的一个栈:
#include<iostream>
#include <stack>
using namespace std;
template<typename T>
class TyStack
{
private:
struct Node
{
struct Node*next;
T m_data;
};
Node *m_pCur{nullptr};
int m_nCurSize{ 0 };
public:
T top()
{
if (m_pCur)
{
return m_pCur->m_data;
}
}
void push(T data)
{
if (!m_pCur)
{
Node *m_pnew = (Node *)malloc(sizeof(Node));
m_pnew->m_data = data;
m_pnew->next = nullptr;
m_pCur = m_pnew;
}
else
{
Node *m_pnew = (Node *)malloc(sizeof(Node));
m_pnew->m_data = data;
m_pnew->next = m_pCur;
m_pCur = m_pnew;
}
m_nCurSize++;
}
void pop()
{
if (m_nCurSize>=1)
{
Node *m_temp = m_pCur->next;
free(m_pCur);
m_pCur = NULL;
m_pCur = m_temp;
m_nCurSize--;
}
}
};
void main()
{
TyStack<int> m_stack;
m_stack.push(1);
m_stack.push(2);
m_stack.push(3);
m_stack.push(4);
int a = m_stack.top();
m_stack.pop();
cout << a << endl;
a = m_stack.top();
m_stack.pop();
cout << a << endl;
m_stack.push(100);
m_stack.push(200);
a = m_stack.top();
m_stack.pop();
cout << a << endl;
a = m_stack.top();
m_stack.pop();
cout << a << endl;
a = m_stack.top();
m_stack.pop();
cout << a << endl;
a = m_stack.top();
m_stack.pop();
cout << a << endl;
system("pause");
}
结果: