一.栈(定义说明)
C++的栈是一种数据结构,是只允许在一端进行插入删除操作的线性表,它是一个后进先出(LIFO)的线性结构,具有两个基本操作:push和pop。push操作将数据压入栈顶,而pop操作将栈顶数据弹出。
在C++中,栈通常用于实现函数调用堆栈和表达式求值等场景。当一个函数被调用时,它的返回地址和其他必要数据被压入栈中,当函数返回时,这些数据被弹出。
栈有两种基本存储方式:
(1)顺序存储:利用一段连续的内存空间进行存储。
(2)链式存储:利用非连续的内存空间存储,元素之间使用指针进行链接。(通常单链表实现,栈顶是表头,栈底的表尾)
二.顺序栈
2.1 定义说明
采用顺序存储的栈,它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针(top)指示当前栈顶元素的位置。
2.2 程序说明
2.2.1 栈的顺序存储类型
typedef struct {
Elemtype data[Maxsize];
int top; //栈顶指针
}SqStack;
2.2.2 初始化
void InitStack(SqStack& S)
{
S.top = -1;
}
2.2.3 进栈
bool Push(SqStack& S, Elemtype x)
{
if (S.top == Maxsize - 1)
return false;
S.data[++S.top] = x; //top指针先加1,指向下一个位置,数据入栈
return true;
}
2.2.4 出栈
bool Pop(SqStack& S, Elemtype& x)
{
if (S.top == -1)
return false;
x = S.data[S.top--]; //先出栈,top指针再减1,指向前一个位置
return true;
}
2.2.5 遍历
void PrintStack(SqStack& S)
{
for (int i = 0; i <= S.top; i++)
{
cout << S.data[i] << " ";
}
cout << endl;
}
2.2.6 判断栈空
bool StackEmpty(SqStack& S)
{
if (S.top == -1)
return true; //空
else
return false; //非空
}
2.2.7 主函数
int main()
{
SqStack S;
InitStack(S);
int n;
//(1)入栈数据
cout << "(最多10个)想要入栈几个数据:" << endl;
cin >> n;
for (int i = 0; i < n; i++)
{
int j;
cin >> j;
Push(S, j);
}
PrintStack(S);
//(2)出栈
int m; //m为栈顶
Pop(S, m);
PrintStack(S);
cout << "栈顶元素:" << m << endl; //其实栈顶也可以是 S.data[S.top]
system("pause");
return 0;
}
2.3 小结思考
其实跟顺序表很相似,区别在于插入和删除在一端进行。
三.链栈
3.1 定义说明
链栈是指采用链式存储结构实现的栈,通常用单链表来表示。它的特点是:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续也可以是不连续),便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况。
规定:所有操作都是在单链表的表头进行,链栈是没有头结点的,LinkStack(程序中的S)指向栈顶元素。
3.2 程序说明
3.2.1 栈的链式存储类型
//链式存储类型
typedef struct Linknode {
Elemtype data;
struct Linknode* next;
}*LiStack;
3.2.2 初始化
bool InitStack(LiStack& S)
{
S = NULL;
return true;
}
3.2.3 进栈
void Push(LiStack& S,Elemtype e)
{
Linknode* p = new Linknode;
p->data = e;
p->next = S;
S = p;
}
3.2.4 出栈
void Pop(LiStack& S)
{
Linknode* p = S;
S = S->next;
free(p);
}
3.2.5 遍历
bool PrintStack(LiStack& S)
{
Linknode* p = S;
if (p == NULL)
{
cout << "链栈为空!" << endl;
return false;
}
cout << "栈顶->栈底:";
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
return true;
}
3.2.6 主函数
int main()
{
LiStack S;
InitStack(S);
//(1)入栈
int n;
cout << "想要入栈几个数据:" << endl;
cin >> n;
for (int i = 0; i < n; i++)
{
int j;
cin >> j;
Push(S, j);
}
PrintStack(S);
//(2)出栈
Pop(S);
PrintStack(S);
system("pause");
return 0;
}
3.3 小结思考
链栈也和单链表相似,但容易得多,只在链首进行操作,没有头结点。