采用顺序存储结构的栈称为顺序栈,即需要用一片地址连续的空间来存储栈的元素,很容易想到用一个一维数组实现,并指定栈顶位于序列末端。顺序栈的表示有很多种,下面我们就用C语言来看看顺序栈的表示。
1. 使用 top
表示栈顶位置
typedef struct {
ElemType *elem; // 存储空间的基址
int top; // 栈顶元素的下一个位置,简称栈顶位标
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack;
特点
1.这里的 top
表示的是栈顶元素的下一个位置。这意味着 top 指向栈中实际元素的数量,因此栈为空时 top
为0,栈满时 top
等于 size
。
2.常用于顺序栈的基本实现中,比较直观。
常见操作接口
InitStack
:初始化栈,分配初始的存储空间。StackEmpty
:判断栈是否为空,空栈返回OK
,否则返回ERROR
。StackLength
:返回栈的当前长度,即栈中元素的数量。GetTop
:获取栈顶元素,栈顶元素通过参数e
返回。Push
:将元素入栈,如果栈满则自动扩容。Pop
:将栈顶元素出栈,并通过参数e
返回该元素。DestroyStack
:销毁栈,释放所有分配的内存。ClearStack
:清空栈,只需将top
重置为0。TraverseStack
:遍历栈并打印所有栈中的元素。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType; // 根据实际需要定义元素类型
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct {
ElemType *elem; // 存储空间的基址
int top; // 栈顶元素的下一个位置,简称栈顶位标
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack;
// 初始化栈
Status InitStack(SqStack &S, int initial_size, int increment) {
S.elem = (ElemType *)malloc(initial_size * sizeof(ElemType));
if (!S.elem) return OVERFLOW; // 分配失败
S.top = 0; // 栈顶初始化为0
S.size = initial_size;
S.increment = increment;
return OK;
}
// 判断栈是否为空
Status StackEmpty(SqStack S) {
return S.top == 0 ? OK : ERROR;
}
// 获取栈的长度
int StackLength(SqStack S) {
return S.top;
}
// 获取栈顶元素
Status GetTop(SqStack S, ElemType &e) {
if (S.top == 0) return ERROR; // 栈空
e = S.elem[S.top - 1]; // 栈顶元素在 top - 1 位置
return OK;
}
// 入栈操作
Status Push(SqStack &S, ElemType e) {
if (S.top >= S.size) { // 如果栈满,则需要扩容
ElemType *newbase = (ElemType *)realloc(S.elem, (S.size + S.increment) * sizeof(ElemType));
if (!newbase) return OVERFLOW; // 分配失败
S.elem = newbase;
S.size += S.increment;
}
S.elem[S.top++] = e; // 元素入栈,top 后移
return OK;
}
// 出栈操作
Status Pop(SqStack &S, ElemType &e) {
if (S.top == 0) return ERROR; // 栈空
e = S.elem[--S.top]; // 栈顶元素出栈,top 前移
return OK;
}
// 销毁栈
Status DestroyStack(SqStack &S) {
if (S.elem) {
free(S.elem);
S.elem = NULL;
}
S.top = 0;
S.size = 0;
return OK;
}
// 清空栈
Status ClearStack(SqStack &S) {
S.top = 0; // 只需将栈顶位置重置为0
return OK;
}
// 遍历栈并打印栈中的所有元素
void TraverseStack(SqStack S) {
printf("Stack elements: ");
for (int i = 0; i < S.top; i++) {
printf("%d ", S.elem[i]);
}
printf("\n");
}
int main() {
SqStack S;
ElemType e;
// 初始化栈
if (InitStack(S, 10, 5) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 15; i++) {
if (Push(S, i) == OK) {
printf("Element %d pushed onto stack.\n", i);
}
}
// 获取栈顶元素
if (GetTop(S, e) == OK) {
printf("Top element: %d\n", e);
}
// 遍历栈
TraverseStack(S);
// 出栈操作
while (Pop(S, e) == OK) {
printf("Element %d popped from stack.\n", e);
}
// 销毁栈
DestroyStack(S);
return 0;
}
2. 使用 length
表示栈的长度
typedef struct {
ElemType *elem; // 存储空间的基址
int length; // 栈的长度(即栈中的元素数量)
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack;
特点
1.这里使用 length
来表示栈中的元素数量,这实际上和上一个例子中的 top
表示的含义类似。
2.这种表示更直观地描述了栈的长度,而 length
可以更清晰地表达栈中当前的元素数量。
常见接口操作
InitStack
:初始化栈,分配初始的存储空间。StackEmpty
:判断栈是否为空,空栈返回OK
,否则返回ERROR
。StackLength
:返回栈的当前长度,即栈中元素的数量。GetTop
:获取栈顶元素,栈顶元素通过参数e
返回。Push
:将元素入栈,如果栈满则自动扩容。Pop
:将栈顶元素出栈,并通过参数e
返回该元素。DestroyStack
:销毁栈,释放所有分配的内存。ClearStack
:清空栈,只需将length
重置为0。TraverseStack
:遍历栈并打印所有栈中的元素。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType; // 根据实际需要定义元素类型
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct {
ElemType *elem; // 存储空间的基址
int length; // 栈的长度,即栈中元素的数量
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack;
// 初始化栈
Status InitStack(SqStack &S, int initial_size, int increment) {
S.elem = (ElemType *)malloc(initial_size * sizeof(ElemType));
if (!S.elem) return OVERFLOW; // 分配失败
S.length = 0; // 栈的初始长度为0
S.size = initial_size;
S.increment = increment;
return OK;
}
// 判断栈是否为空
Status StackEmpty(SqStack S) {
return S.length == 0 ? OK : ERROR;
}
// 获取栈的长度
int StackLength(SqStack S) {
return S.length;
}
// 获取栈顶元素
Status GetTop(SqStack S, ElemType &e) {
if (S.length == 0) return ERROR; // 栈空
e = S.elem[S.length - 1]; // 栈顶元素在 length - 1 位置
return OK;
}
// 入栈操作
Status Push(SqStack &S, ElemType e) {
if (S.length >= S.size) { // 如果栈满,则需要扩容
ElemType *newbase = (ElemType *)realloc(S.elem, (S.size + S.increment) * sizeof(ElemType));
if (!newbase) return OVERFLOW; // 分配失败
S.elem = newbase;
S.size += S.increment;
}
S.elem[S.length++] = e; // 元素入栈,length 增加
return OK;
}
// 出栈操作
Status Pop(SqStack &S, ElemType &e) {
if (S.length == 0) return ERROR; // 栈空
e = S.elem[--S.length]; // 栈顶元素出栈,length 减少
return OK;
}
// 销毁栈
Status DestroyStack(SqStack &S) {
if (S.elem) {
free(S.elem);
S.elem = NULL;
}
S.length = 0;
S.size = 0;
return OK;
}
// 清空栈
Status ClearStack(SqStack &S) {
S.length = 0; // 只需将栈长度重置为0
return OK;
}
// 遍历栈并打印栈中的所有元素
void TraverseStack(SqStack S) {
printf("Stack elements: ");
for (int i = 0; i < S.length; i++) {
printf("%d ", S.elem[i]);
}
printf("\n");
}
int main() {
SqStack S;
ElemType e;
// 初始化栈
if (InitStack(S, 10, 5) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 15; i++) {
if (Push(S, i) == OK) {
printf("Element %d pushed onto stack.\n", i);
}
}
// 获取栈顶元素
if (GetTop(S, e) == OK) {
printf("Top element: %d\n", e);
}
// 遍历栈
TraverseStack(S);
// 出栈操作
while (Pop(S, e) == OK) {
printf("Element %d popped from stack.\n", e);
}
// 销毁栈
DestroyStack(S);
return 0;
}
3. 使用指针 top
指向栈顶位置
typedef struct {
ElemType *elem; // 存储空间的基址
ElemType *top; // 栈顶指针,指向栈顶元素的下一个位置
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack;
特点
1.top
是指针类型,指向栈顶元素的下一个位置。通过指针运算可以直接访问栈顶元素。
2.这种表示方式在操作指针时比较高效,可以直接操作内存地址。
常见接口操作
InitStack
:初始化栈,分配初始的存储空间,并设置top
指针指向elem
的基址。StackEmpty
:判断栈是否为空,空栈时top
等于elem
的基址。StackLength
:返回栈的当前长度,计算top
和elem
基址之间的距离。GetTop
:获取栈顶元素,栈顶元素通过参数e
返回。Push
:将元素入栈,如果栈满则自动扩容。Pop
:将栈顶元素出栈,并通过参数e
返回该元素。DestroyStack
:销毁栈,释放所有分配的内存。ClearStack
:清空栈,只需将top
重置为elem
基址。TraverseStack
:遍历栈并打印所有栈中的元素。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType; // 根据实际需要定义元素类型
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct {
ElemType *elem; // 存储空间的基址
ElemType *top; // 栈顶指针,指向栈顶元素的下一个位置
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack;
// 初始化栈
Status InitStack(SqStack &S, int initial_size, int increment) {
S.elem = (ElemType *)malloc(initial_size * sizeof(ElemType));
if (!S.elem) return OVERFLOW; // 分配失败
S.top = S.elem; // 初始时,top 指向 elem 基址,表示栈为空
S.size = initial_size;
S.increment = increment;
return OK;
}
// 判断栈是否为空
Status StackEmpty(SqStack S) {
return S.top == S.elem ? OK : ERROR;
}
// 获取栈的长度
int StackLength(SqStack S) {
return S.top - S.elem; // 栈的长度为 top 指针和 elem 基址之间的距离
}
// 获取栈顶元素
Status GetTop(SqStack S, ElemType &e) {
if (S.top == S.elem) return ERROR; // 栈空
e = *(S.top - 1); // 栈顶元素在 top - 1 位置
return OK;
}
// 入栈操作
Status Push(SqStack &S, ElemType e) {
if (S.top - S.elem >= S.size) { // 如果栈满,则需要扩容
int new_size = S.size + S.increment;
ElemType *newbase = (ElemType *)realloc(S.elem, new_size * sizeof(ElemType));
if (!newbase) return OVERFLOW; // 分配失败
S.top = newbase + (S.top - S.elem); // 更新 top 指针位置
S.elem = newbase;
S.size = new_size;
}
*(S.top++) = e; // 元素入栈,top 后移
return OK;
}
// 出栈操作
Status Pop(SqStack &S, ElemType &e) {
if (S.top == S.elem) return ERROR; // 栈空
e = *(--S.top); // 栈顶元素出栈,top 前移
return OK;
}
// 销毁栈
Status DestroyStack(SqStack &S) {
if (S.elem) {
free(S.elem);
S.elem = NULL;
}
S.top = NULL;
S.size = 0;
return OK;
}
// 清空栈
Status ClearStack(SqStack &S) {
S.top = S.elem; // 只需将 top 重置为 elem 基址
return OK;
}
// 遍历栈并打印栈中的所有元素
void TraverseStack(SqStack S) {
printf("Stack elements: ");
for (ElemType *p = S.elem; p < S.top; p++) {
printf("%d ", *p);
}
printf("\n");
}
int main() {
SqStack S;
ElemType e;
// 初始化栈
if (InitStack(S, 10, 5) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 15; i++) {
if (Push(S, i) == OK) {
printf("Element %d pushed onto stack.\n", i);
}
}
// 获取栈顶元素
if (GetTop(S, e) == OK) {
printf("Top element: %d\n", e);
}
// 遍历栈
TraverseStack(S);
// 出栈操作
while (Pop(S, e) == OK) {
printf("Element %d popped from stack.\n", e);
}
// 销毁栈
DestroyStack(S);
return 0;
}
4. 使用 top
表示栈顶元素位置
typedef struct {
ElemType *elem; // 存储空间的基址
int top; // 栈顶元素的位置
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack;
特点
1.top
直接表示栈顶元素的位置。栈顶元素的索引为 top
,栈顶上方的空位为 top + 1
。
2.这种表示方式与上面几种方式相比稍有不同,但可以更直接地索引栈顶元素。
常见接口操作
InitStack
:初始化栈,分配初始的存储空间,并设置top
为 -1,表示栈为空。StackEmpty
:判断栈是否为空,空栈时top
为 -1。StackLength
:返回栈的当前长度,top + 1
即为栈中元素的数量。GetTop
:获取栈顶元素,栈顶元素通过参数e
返回。Push
:将元素入栈,如果栈满则自动扩容。Pop
:将栈顶元素出栈,并通过参数e
返回该元素。DestroyStack
:销毁栈,释放所有分配的内存。ClearStack
:清空栈,只需将top
重置为 -1。TraverseStack
:遍历栈并打印所有栈中的元素。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType; // 根据实际需要定义元素类型
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct {
ElemType *elem; // 存储空间的基址
int top; // 栈顶位置
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack;
// 初始化栈
Status InitStack(SqStack &S, int initial_size, int increment) {
S.elem = (ElemType *)malloc(initial_size * sizeof(ElemType));
if (!S.elem) return OVERFLOW; // 分配失败
S.top = -1; // 栈顶位置初始化为-1,表示栈为空
S.size = initial_size;
S.increment = increment;
return OK;
}
// 判断栈是否为空
Status StackEmpty(SqStack S) {
return S.top == -1 ? OK : ERROR;
}
// 获取栈的长度
int StackLength(SqStack S) {
return S.top + 1; // 栈的长度为 top + 1
}
// 获取栈顶元素
Status GetTop(SqStack S, ElemType &e) {
if (S.top == -1) return ERROR; // 栈空
e = S.elem[S.top]; // 栈顶元素在 top 位置
return OK;
}
// 入栈操作
Status Push(SqStack &S, ElemType e) {
if (S.top >= S.size - 1) { // 如果栈满,则需要扩容
ElemType *newbase = (ElemType *)realloc(S.elem, (S.size + S.increment) * sizeof(ElemType));
if (!newbase) return OVERFLOW; // 分配失败
S.elem = newbase;
S.size += S.increment;
}
S.elem[++S.top] = e; // 元素入栈,top 增加
return OK;
}
// 出栈操作
Status Pop(SqStack &S, ElemType &e) {
if (S.top == -1) return ERROR; // 栈空
e = S.elem[S.top--]; // 栈顶元素出栈,top 减少
return OK;
}
// 销毁栈
Status DestroyStack(SqStack &S) {
if (S.elem) {
free(S.elem);
S.elem = NULL;
}
S.top = -1;
S.size = 0;
return OK;
}
// 清空栈
Status ClearStack(SqStack &S) {
S.top = -1; // 只需将 top 重置为 -1
return OK;
}
// 遍历栈并打印栈中的所有元素
void TraverseStack(SqStack S) {
printf("Stack elements: ");
for (int i = 0; i <= S.top; i++) {
printf("%d ", S.elem[i]);
}
printf("\n");
}
int main() {
SqStack S;
ElemType e;
// 初始化栈
if (InitStack(S, 10, 5) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 15; i++) {
if (Push(S, i) == OK) {
printf("Element %d pushed onto stack.\n", i);
}
}
// 获取栈顶元素
if (GetTop(S, e) == OK) {
printf("Top element: %d\n", e);
}
// 遍历栈
TraverseStack(S);
// 出栈操作
while (Pop(S, e) == OK) {
printf("Element %d popped from stack.\n", e);
}
// 销毁栈
DestroyStack(S);
return 0;
}
5. 使用指针 top
指向栈顶元素位置
typedef struct {
ElemType *elem; // 存储空间的基址
ElemType *top; // 栈顶指针,指向栈顶元素的位置
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack;
特点
1.top
是指针,指向栈顶元素的位置,而不是下一个位置。通过指针运算可以直接获取或修改栈顶元素的值。
2.这种表示方式更接近实际的硬件栈指针操作,用于需要精确控制栈顶元素的场景。
常见操作接口
InitStack
:初始化栈,分配初始的存储空间,并设置top
为elem - 1
,表示栈为空。StackEmpty
:判断栈是否为空,空栈时top
指针位置小于elem
基址。StackLength
:返回栈的当前长度,即top
和elem
基址之间的距离加1。GetTop
:获取栈顶元素,栈顶元素通过参数e
返回。Push
:将元素入栈,如果栈满则自动扩容。Pop
:将栈顶元素出栈,并通过参数e
返回该元素。DestroyStack
:销毁栈,释放所有分配的内存。ClearStack
:清空栈,只需将top
重置为elem - 1
。TraverseStack
:遍历栈并打印所有栈中的元素。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType; // 根据实际需要定义元素类型
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct {
ElemType *elem; // 存储空间的基址
ElemType *top; // 栈顶指针,指向栈顶元素位置
int size; // 当前分配的存储容量
int increment; // 扩容时,增加的存储容量
} SqStack;
// 初始化栈
Status InitStack(SqStack &S, int initial_size, int increment) {
S.elem = (ElemType *)malloc(initial_size * sizeof(ElemType));
if (!S.elem) return OVERFLOW; // 分配失败
S.top = S.elem - 1; // 初始化时,top 指向栈底元素前一个位置,表示栈为空
S.size = initial_size;
S.increment = increment;
return OK;
}
// 判断栈是否为空
Status StackEmpty(SqStack S) {
return S.top < S.elem ? OK : ERROR;
}
// 获取栈的长度
int StackLength(SqStack S) {
return S.top - S.elem + 1; // 栈的长度为 top 和 elem 基址之间的距离
}
// 获取栈顶元素
Status GetTop(SqStack S, ElemType &e) {
if (S.top < S.elem) return ERROR; // 栈空
e = *S.top; // 栈顶元素
return OK;
}
// 入栈操作
Status Push(SqStack &S, ElemType e) {
if (S.top - S.elem + 1 >= S.size) { // 如果栈满,则需要扩容
int new_size = S.size + S.increment;
ElemType *newbase = (ElemType *)realloc(S.elem, new_size * sizeof(ElemType));
if (!newbase) return OVERFLOW; // 分配失败
S.top = newbase + (S.top - S.elem); // 更新 top 指针位置
S.elem = newbase;
S.size = new_size;
}
*(++S.top) = e; // 元素入栈,top 后移
return OK;
}
// 出栈操作
Status Pop(SqStack &S, ElemType &e) {
if (S.top < S.elem) return ERROR; // 栈空
e = *(S.top--); // 栈顶元素出栈,top 前移
return OK;
}
// 销毁栈
Status DestroyStack(SqStack &S) {
if (S.elem) {
free(S.elem);
S.elem = NULL;
}
S.top = NULL;
S.size = 0;
return OK;
}
// 清空栈
Status ClearStack(SqStack &S) {
S.top = S.elem - 1; // 只需将 top 重置为 elem 前一个位置
return OK;
}
// 遍历栈并打印栈中的所有元素
void TraverseStack(SqStack S) {
printf("Stack elements: ");
for (ElemType *p = S.elem; p <= S.top; p++) {
printf("%d ", *p);
}
printf("\n");
}
int main() {
SqStack S;
ElemType e;
// 初始化栈
if (InitStack(S, 10, 5) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 15; i++) {
if (Push(S, i) == OK) {
printf("Element %d pushed onto stack.\n", i);
}
}
// 获取栈顶元素
if (GetTop(S, e) == OK) {
printf("Top element: %d\n", e);
}
// 遍历栈
TraverseStack(S);
// 出栈操作
while (Pop(S, e) == OK) {
printf("Element %d popped from stack.\n", e);
}
// 销毁栈
DestroyStack(S);
return 0;
}
6. 基于固定大小的数组实现顺序栈
#define MAXSIZE 1000
ElemType S[MAXSIZE];
typedef struct {
ElemType elem[MAXSIZE]; // 固定大小的数组用于存储栈中的元素
int top; // 栈顶位置,指向栈顶元素的下一个位置
} SqStack_Fixed;
特点
1.使用一个固定大小的数组 S
来表示顺序栈,MAXSIZE
是栈的最大容量。
2.这种表示方式简单且直接,适用于栈容量固定且不需要扩展的情况,如静态栈或嵌入式系统中。
常见接口操作
InitStack
:初始化栈,设置top
为 0,表示栈为空。StackEmpty
:判断栈是否为空,空栈时top
为 0。StackLength
:返回栈的当前长度,直接返回top
的值。GetTop
:获取栈顶元素,栈顶元素通过参数e
返回。Push
:将元素入栈,如果栈满则返回错误。Pop
:将栈顶元素出栈,并通过参数e
返回该元素。ClearStack
:清空栈,只需将top
重置为 0。TraverseStack
:遍历栈并打印所有栈中的元素。
#include <stdio.h>
#define MAXSIZE 100 // 根据实际需求设置栈的最大容量
typedef int ElemType; // 根据实际需要定义元素类型
#define OK 1
#define ERROR 0
typedef int Status;
typedef struct {
ElemType elem[MAXSIZE]; // 固定大小的数组用于存储栈中的元素
int top; // 栈顶位置,指向栈顶元素的下一个位置
} SqStack_Fixed;
// 初始化栈
Status InitStack(SqStack_Fixed &S) {
S.top = 0; // 初始化时,top 为 0,表示栈为空
return OK;
}
// 判断栈是否为空
Status StackEmpty(SqStack_Fixed S) {
return S.top == 0 ? OK : ERROR;
}
// 获取栈的长度
int StackLength(SqStack_Fixed S) {
return S.top; // 栈的长度为 top
}
// 获取栈顶元素
Status GetTop(SqStack_Fixed S, ElemType &e) {
if (S.top == 0) return ERROR; // 栈空
e = S.elem[S.top - 1]; // 栈顶元素在 top - 1 位置
return OK;
}
// 入栈操作
Status Push(SqStack_Fixed &S, ElemType e) {
if (S.top >= MAXSIZE) return ERROR; // 栈满
S.elem[S.top++] = e; // 元素入栈,top 后移
return OK;
}
// 出栈操作
Status Pop(SqStack_Fixed &S, ElemType &e) {
if (S.top == 0) return ERROR; // 栈空
e = S.elem[--S.top]; // 栈顶元素出栈,top 前移
return OK;
}
// 清空栈
Status ClearStack(SqStack_Fixed &S) {
S.top = 0; // 只需将 top 重置为 0
return OK;
}
// 遍历栈并打印栈中的所有元素
void TraverseStack(SqStack_Fixed S) {
printf("Stack elements: ");
for (int i = 0; i < S.top; i++) {
printf("%d ", S.elem[i]);
}
printf("\n");
}
int main() {
SqStack_Fixed S;
ElemType e;
// 初始化栈
if (InitStack(S) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 10; i++) {
if (Push(S, i) == OK) {
printf("Element %d pushed onto stack.\n", i);
}
}
// 获取栈顶元素
if (GetTop(S, e) == OK) {
printf("Top element: %d\n", e);
}
// 遍历栈
TraverseStack(S);
// 出栈操作
while (Pop(S, e) == OK) {
printf("Element %d popped from stack.\n", e);
}
// 清空栈
ClearStack(S);
// 遍历栈,检查是否清空
TraverseStack(S);
return 0;
}
7.基于动态数组实现顺序栈
typedef struct {
ElemType *elem; // 动态分配的数组基址
int top; // 栈顶位置,指向栈顶元素的下一个位置
int size; // 当前栈的容量
} SqStack_Dynamic;
特点
这种方式使用动态分配的数组来实现顺序栈,并在需要时扩展栈的容量。它比固定大小的数组更灵活。
常见操作接口
InitStack
:初始化栈,分配初始的存储空间,并设置top
为 0,表示栈为空。StackEmpty
:判断栈是否为空,空栈时top
为 0。StackLength
:返回栈的当前长度,直接返回top
的值。GetTop
:获取栈顶元素,栈顶元素通过参数e
返回。ExpandStack
:扩容操作,当栈满时,增加栈的存储容量。Push
:将元素入栈,如果栈满则自动扩容。Pop
:将栈顶元素出栈,并通过参数e
返回该元素。DestroyStack
:销毁栈,释放所有分配的内存。ClearStack
:清空栈,只需将top
重置为 0。TraverseStack
:遍历栈并打印所有栈中的元素。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType; // 根据实际需要定义元素类型
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct {
ElemType *elem; // 动态分配的数组基址
int top; // 栈顶位置,指向栈顶元素的下一个位置
int size; // 当前栈的容量
} SqStack_Dynamic;
// 初始化栈
Status InitStack(SqStack_Dynamic &S, int initial_size) {
S.elem = (ElemType *)malloc(initial_size * sizeof(ElemType));
if (!S.elem) return OVERFLOW; // 分配失败
S.top = 0; // 初始化时,top 为 0,表示栈为空
S.size = initial_size;
return OK;
}
// 判断栈是否为空
Status StackEmpty(SqStack_Dynamic S) {
return S.top == 0 ? OK : ERROR;
}
// 获取栈的长度
int StackLength(SqStack_Dynamic S) {
return S.top; // 栈的长度为 top
}
// 获取栈顶元素
Status GetTop(SqStack_Dynamic S, ElemType &e) {
if (S.top == 0) return ERROR; // 栈空
e = S.elem[S.top - 1]; // 栈顶元素在 top - 1 位置
return OK;
}
// 扩容操作
Status ExpandStack(SqStack_Dynamic &S, int increment) {
ElemType *newbase = (ElemType *)realloc(S.elem, (S.size + increment) * sizeof(ElemType));
if (!newbase) return OVERFLOW; // 分配失败
S.elem = newbase;
S.size += increment;
return OK;
}
// 入栈操作
Status Push(SqStack_Dynamic &S, ElemType e) {
if (S.top >= S.size) { // 如果栈满,则需要扩容
if (ExpandStack(S, S.size) != OK) { // 扩容失败返回错误
return OVERFLOW;
}
}
S.elem[S.top++] = e; // 元素入栈,top 后移
return OK;
}
// 出栈操作
Status Pop(SqStack_Dynamic &S, ElemType &e) {
if (S.top == 0) return ERROR; // 栈空
e = S.elem[--S.top]; // 栈顶元素出栈,top 前移
return OK;
}
// 销毁栈
Status DestroyStack(SqStack_Dynamic &S) {
if (S.elem) {
free(S.elem);
S.elem = NULL;
}
S.top = 0;
S.size = 0;
return OK;
}
// 清空栈
Status ClearStack(SqStack_Dynamic &S) {
S.top = 0; // 只需将 top 重置为 0
return OK;
}
// 遍历栈并打印栈中的所有元素
void TraverseStack(SqStack_Dynamic S) {
printf("Stack elements: ");
for (int i = 0; i < S.top; i++) {
printf("%d ", S.elem[i]);
}
printf("\n");
}
int main() {
SqStack_Dynamic S;
ElemType e;
// 初始化栈
if (InitStack(S, 5) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 10; i++) {
if (Push(S, i) == OK) {
printf("Element %d pushed onto stack.\n", i);
}
}
// 获取栈顶元素
if (GetTop(S, e) == OK) {
printf("Top element: %d\n", e);
}
// 遍历栈
TraverseStack(S);
// 出栈操作
while (Pop(S, e) == OK) {
printf("Element %d popped from stack.\n", e);
}
// 清空栈
ClearStack(S);
// 销毁栈
DestroyStack(S);
return 0;
}
8.带有最小栈功能的顺序栈
typedef struct {
ElemType *elem; // 动态分配的数组基址
int top; // 栈顶位置,指向栈顶元素的下一个位置
int size; // 当前栈的容量
ElemType *minElem; // 存储最小值的栈
int minTop; // 最小值栈的栈顶位置
} SqStack_Min;
特点
这种顺序栈在每次操作栈时,同时维护一个存储最小值的栈,用于实现快速获取栈中的最小值。
常见操作接口
InitStack
:初始化栈,分配初始的存储空间,并设置top
和minTop
为 0,表示栈为空。StackEmpty
:判断栈是否为空,空栈时top
为 0。StackLength
:返回栈的当前长度,直接返回top
的值。GetTop
:获取栈顶元素,栈顶元素通过参数e
返回。GetMin
:获取栈中的最小值,通过维护一个最小值栈实现,最小值通过参数e
返回。ExpandStack
:扩容操作,当栈满时,增加栈和最小值栈的存储容量。Push
:将元素入栈,如果栈满则自动扩容,同时更新最小值栈。Pop
:将栈顶元素出栈,并通过参数e
返回该元素,同时更新最小值栈。DestroyStack
:销毁栈,释放所有分配的内存,包括最小值栈。ClearStack
:清空栈,并清空最小值栈。TraverseStack
:遍历栈并打印所有栈中的元素。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType; // 根据实际需要定义元素类型
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct {
ElemType *elem; // 动态分配的数组基址
int top; // 栈顶位置,指向栈顶元素的下一个位置
int size; // 当前栈的容量
ElemType *minElem; // 存储最小值的栈
int minTop; // 最小值栈的栈顶位置
} SqStack_Min;
// 初始化栈
Status InitStack(SqStack_Min &S, int initial_size) {
S.elem = (ElemType *)malloc(initial_size * sizeof(ElemType));
S.minElem = (ElemType *)malloc(initial_size * sizeof(ElemType));
if (!S.elem || !S.minElem) return OVERFLOW; // 分配失败
S.top = 0;
S.minTop = 0;
S.size = initial_size;
return OK;
}
// 判断栈是否为空
Status StackEmpty(SqStack_Min S) {
return S.top == 0 ? OK : ERROR;
}
// 获取栈的长度
int StackLength(SqStack_Min S) {
return S.top; // 栈的长度为 top
}
// 获取栈顶元素
Status GetTop(SqStack_Min S, ElemType &e) {
if (S.top == 0) return ERROR; // 栈空
e = S.elem[S.top - 1]; // 栈顶元素在 top - 1 位置
return OK;
}
// 获取栈中的最小值
Status GetMin(SqStack_Min S, ElemType &e) {
if (S.minTop == 0) return ERROR; // 最小值栈为空
e = S.minElem[S.minTop - 1]; // 最小值栈顶元素
return OK;
}
// 扩容操作
Status ExpandStack(SqStack_Min &S, int increment) {
ElemType *newbase = (ElemType *)realloc(S.elem, (S.size + increment) * sizeof(ElemType));
ElemType *newMinBase = (ElemType *)realloc(S.minElem, (S.size + increment) * sizeof(ElemType));
if (!newbase || !newMinBase) return OVERFLOW; // 分配失败
S.elem = newbase;
S.minElem = newMinBase;
S.size += increment;
return OK;
}
// 入栈操作
Status Push(SqStack_Min &S, ElemType e) {
if (S.top >= S.size) { // 如果栈满,则需要扩容
if (ExpandStack(S, S.size) != OK) { // 扩容失败返回错误
return OVERFLOW;
}
}
S.elem[S.top++] = e; // 元素入栈,top 后移
// 处理最小值栈
if (S.minTop == 0 || e <= S.minElem[S.minTop - 1]) {
S.minElem[S.minTop++] = e; // 将当前元素入最小值栈
}
return OK;
}
// 出栈操作
Status Pop(SqStack_Min &S, ElemType &e) {
if (S.top == 0) return ERROR; // 栈空
e = S.elem[--S.top]; // 栈顶元素出栈,top 前移
// 处理最小值栈
if (e == S.minElem[S.minTop - 1]) {
--S.minTop; // 同步从最小值栈中出栈
}
return OK;
}
// 销毁栈
Status DestroyStack(SqStack_Min &S) {
if (S.elem) {
free(S.elem);
S.elem = NULL;
}
if (S.minElem) {
free(S.minElem);
S.minElem = NULL;
}
S.top = 0;
S.minTop = 0;
S.size = 0;
return OK;
}
// 清空栈
Status ClearStack(SqStack_Min &S) {
S.top = 0; // 只需将 top 重置为 0
S.minTop = 0; // 同时清空最小值栈
return OK;
}
// 遍历栈并打印栈中的所有元素
void TraverseStack(SqStack_Min S) {
printf("Stack elements: ");
for (int i = 0; i < S.top; i++) {
printf("%d ", S.elem[i]);
}
printf("\n");
}
int main() {
SqStack_Min S;
ElemType e;
// 初始化栈
if (InitStack(S, 5) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 10; i++) {
if (Push(S, i) == OK) {
printf("Element %d pushed onto stack.\n", i);
}
}
// 获取栈顶元素
if (GetTop(S, e) == OK) {
printf("Top element: %d\n", e);
}
// 获取最小值
if (GetMin(S, e) == OK) {
printf("Minimum element: %d\n", e);
}
// 遍历栈
TraverseStack(S);
// 出栈操作
while (Pop(S, e) == OK) {
printf("Element %d popped from stack.\n", e);
}
// 清空栈
ClearStack(S);
// 销毁栈
DestroyStack(S);
return 0;
}
9.顺序栈的环形数组实现
typedef struct {
ElemType *elem; // 动态分配的数组基址
int top; // 栈顶位置,指向栈顶元素的下一个位置
int size; // 当前栈的容量
int bottom; // 栈底位置,指向栈底元素
} SqStack_Circular;
特点
这种方式通过环形数组来实现顺序栈,栈满时,指针可以绕回栈底,适用于需要循环使用栈空间的情况。
常见操作接口
InitStack
:初始化栈,分配初始的存储空间,并设置top
和bottom
为 0,表示栈为空。StackEmpty
:判断栈是否为空,空栈时top
等于bottom
。StackLength
:返回栈的当前长度,通过(S.top - S.bottom + S.size) % S.size
计算循环栈的长度。GetTop
:获取栈顶元素,栈顶元素通过参数e
返回。ExpandStack
:扩容操作,当栈满时,增加栈的存储容量,调整栈的顺序。Push
:将元素入栈,如果栈满则自动扩容。Pop
:将栈顶元素出栈,并通过参数e
返回该元素。DestroyStack
:销毁栈,释放所有分配的内存。ClearStack
:清空栈,只需将top
和bottom
重置为 0。TraverseStack
:遍历栈并打印所有栈中的元素。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType; // 根据实际需要定义元素类型
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct {
ElemType *elem; // 动态分配的数组基址
int top; // 栈顶位置,指向栈顶元素的下一个位置
int size; // 当前栈的容量
int bottom; // 栈底位置,指向栈底元素
} SqStack_Circular;
// 初始化栈
Status InitStack(SqStack_Circular &S, int initial_size) {
S.elem = (ElemType *)malloc(initial_size * sizeof(ElemType));
if (!S.elem) return OVERFLOW; // 分配失败
S.top = 0;
S.bottom = 0;
S.size = initial_size;
return OK;
}
// 判断栈是否为空
Status StackEmpty(SqStack_Circular S) {
return S.top == S.bottom ? OK : ERROR;
}
// 获取栈的长度
int StackLength(SqStack_Circular S) {
return (S.top - S.bottom + S.size) % S.size; // 循环计算栈的长度
}
// 获取栈顶元素
Status GetTop(SqStack_Circular S, ElemType &e) {
if (StackEmpty(S)) return ERROR; // 栈空
e = S.elem[(S.top - 1 + S.size) % S.size]; // 栈顶元素在 top - 1 位置
return OK;
}
// 扩容操作
Status ExpandStack(SqStack_Circular &S, int increment) {
ElemType *newbase = (ElemType *)malloc((S.size + increment) * sizeof(ElemType));
if (!newbase) return OVERFLOW; // 分配失败
int length = StackLength(S);
for (int i = 0; i < length; i++) {
newbase[i] = S.elem[(S.bottom + i) % S.size];
}
free(S.elem);
S.elem = newbase;
S.size += increment;
S.bottom = 0;
S.top = length; // 调整栈顶和栈底位置
return OK;
}
// 入栈操作
Status Push(SqStack_Circular &S, ElemType e) {
if ((S.top + 1) % S.size == S.bottom) { // 判断栈是否满
if (ExpandStack(S, S.size) != OK) { // 扩容失败返回错误
return OVERFLOW;
}
}
S.elem[S.top] = e; // 元素入栈
S.top = (S.top + 1) % S.size; // 循环调整栈顶位置
return OK;
}
// 出栈操作
Status Pop(SqStack_Circular &S, ElemType &e) {
if (StackEmpty(S)) return ERROR; // 栈空
S.top = (S.top - 1 + S.size) % S.size; // 循环调整栈顶位置
e = S.elem[S.top]; // 栈顶元素出栈
return OK;
}
// 销毁栈
Status DestroyStack(SqStack_Circular &S) {
if (S.elem) {
free(S.elem);
S.elem = NULL;
}
S.top = 0;
S.bottom = 0;
S.size = 0;
return OK;
}
// 清空栈
Status ClearStack(SqStack_Circular &S) {
S.top = 0; // 清空栈只需重置 top 和 bottom
S.bottom = 0;
return OK;
}
// 遍历栈并打印栈中的所有元素
void TraverseStack(SqStack_Circular S) {
printf("Stack elements: ");
for (int i = S.bottom; i != S.top; i = (i + 1) % S.size) {
printf("%d ", S.elem[i]);
}
printf("\n");
}
int main() {
SqStack_Circular S;
ElemType e;
// 初始化栈
if (InitStack(S, 5) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 10; i++) {
if (Push(S, i) == OK) {
printf("Element %d pushed onto stack.\n", i);
}
}
// 获取栈顶元素
if (GetTop(S, e) == OK) {
printf("Top element: %d\n", e);
}
// 遍历栈
TraverseStack(S);
// 出栈操作
while (Pop(S, e) == OK) {
printf("Element %d popped from stack.\n", e);
}
// 清空栈
ClearStack(S);
// 销毁栈
DestroyStack(S);
return 0;
}
10.支持多栈的顺序栈
#define NUM_STACKS 3 // 假设我们实现3个栈
typedef struct {
ElemType *elem; // 动态分配的数组基址
int tops[NUM_STACKS]; // 每个栈的栈顶指针
int size; // 每个栈的容量,假设所有栈容量相同
} SqStack_Multi;
特点
这种方式在一个数组中同时实现多个栈,每个栈有独立的栈顶指针。
常见操作接口
InitStack
:初始化栈,分配一个动态数组用于存储所有栈的元素,并设置每个栈的栈顶指针为对应栈的起始位置。StackEmpty
:判断指定栈是否为空,空栈时top
等于栈的起始位置。StackLength
:返回指定栈的当前长度,通过栈顶指针减去栈的起始位置计算得到。GetTop
:获取指定栈的栈顶元素,栈顶元素通过参数e
返回。Push
:将元素入指定栈,如果栈满则返回错误。Pop
:将指定栈的栈顶元素出栈,并通过参数e
返回该元素。DestroyStack
:销毁栈,释放所有分配的内存。ClearStack
:清空指定栈,只需将对应栈的栈顶指针重置为该栈的起始位置。TraverseStack
:遍历指定栈并打印所有栈中的元素。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType; // 根据实际需要定义元素类型
#define NUM_STACKS 3 // 假设实现3个栈
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct {
ElemType *elem; // 动态分配的数组基址
int tops[NUM_STACKS]; // 每个栈的栈顶指针
int size; // 每个栈的容量
} SqStack_Multi;
// 初始化栈
Status InitStack(SqStack_Multi &S, int stack_size) {
S.elem = (ElemType *)malloc(NUM_STACKS * stack_size * sizeof(ElemType));
if (!S.elem) return OVERFLOW; // 分配失败
S.size = stack_size;
for (int i = 0; i < NUM_STACKS; i++) {
S.tops[i] = i * stack_size; // 每个栈的初始栈顶指针设置为对应的初始位置
}
return OK;
}
// 判断某个栈是否为空
Status StackEmpty(SqStack_Multi S, int stack_num) {
if (stack_num < 0 || stack_num >= NUM_STACKS) return ERROR; // 无效的栈号
return S.tops[stack_num] == stack_num * S.size ? OK : ERROR;
}
// 获取某个栈的长度
int StackLength(SqStack_Multi S, int stack_num) {
if (stack_num < 0 || stack_num >= NUM_STACKS) return ERROR; // 无效的栈号
return S.tops[stack_num] - stack_num * S.size;
}
// 获取某个栈的栈顶元素
Status GetTop(SqStack_Multi S, int stack_num, ElemType &e) {
if (stack_num < 0 || stack_num >= NUM_STACKS) return ERROR; // 无效的栈号
if (StackEmpty(S, stack_num) == OK) return ERROR; // 栈空
e = S.elem[S.tops[stack_num] - 1];
return OK;
}
// 入栈操作
Status Push(SqStack_Multi &S, int stack_num, ElemType e) {
if (stack_num < 0 || stack_num >= NUM_STACKS) return ERROR; // 无效的栈号
if (S.tops[stack_num] >= (stack_num + 1) * S.size) { // 栈满
return OVERFLOW;
}
S.elem[S.tops[stack_num]++] = e; // 元素入栈,top 后移
return OK;
}
// 出栈操作
Status Pop(SqStack_Multi &S, int stack_num, ElemType &e) {
if (stack_num < 0 || stack_num >= NUM_STACKS) return ERROR; // 无效的栈号
if (StackEmpty(S, stack_num) == OK) return ERROR; // 栈空
e = S.elem[--S.tops[stack_num]]; // 栈顶元素出栈,top 前移
return OK;
}
// 销毁栈
Status DestroyStack(SqStack_Multi &S) {
if (S.elem) {
free(S.elem);
S.elem = NULL;
}
for (int i = 0; i < NUM_STACKS; i++) {
S.tops[i] = 0;
}
S.size = 0;
return OK;
}
// 清空某个栈
Status ClearStack(SqStack_Multi &S, int stack_num) {
if (stack_num < 0 || stack_num >= NUM_STACKS) return ERROR; // 无效的栈号
S.tops[stack_num] = stack_num * S.size; // 重置栈顶指针
return OK;
}
// 遍历某个栈并打印栈中的所有元素
void TraverseStack(SqStack_Multi S, int stack_num) {
if (stack_num < 0 || stack_num >= NUM_STACKS) {
printf("Invalid stack number\n");
return;
}
printf("Stack %d elements: ", stack_num);
for (int i = stack_num * S.size; i < S.tops[stack_num]; i++) {
printf("%d ", S.elem[i]);
}
printf("\n");
}
int main() {
SqStack_Multi S;
ElemType e;
// 初始化栈
if (InitStack(S, 5) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 10; i++) {
if (Push(S, i % NUM_STACKS, i) == OK) {
printf("Element %d pushed onto stack %d.\n", i, i % NUM_STACKS);
}
}
// 获取栈顶元素
for (int i = 0; i < NUM_STACKS; i++) {
if (GetTop(S, i, e) == OK) {
printf("Top element of stack %d: %d\n", i, e);
}
}
// 遍历栈
for (int i = 0; i < NUM_STACKS; i++) {
TraverseStack(S, i);
}
// 出栈操作
for (int i = 0; i < NUM_STACKS; i++) {
if (Pop(S, i, e) == OK) {
printf("Element %d popped from stack %d.\n", e, i);
}
}
// 清空栈
for (int i = 0; i < NUM_STACKS; i++) {
ClearStack(S, i);
}
// 销毁栈
DestroyStack(S);
return 0;
}
11.用链表实现的顺序栈
typedef struct Node {
ElemType data; // 节点存储的数据
struct Node *next; // 指向下一个节点的指针
} StackNode;
typedef struct {
StackNode *top; // 指向栈顶节点的指针
int length; // 栈中元素的数量
} LinkStack;
特点
虽然这种实现不是严格的“顺序栈”,但可以模拟顺序栈的行为。链表节点相当于栈中的每个元素,这样的栈没有容量限制。
常见操作接口
InitStack
:初始化栈,将栈顶指针top
设为NULL
,并将栈长度length
设为 0。StackEmpty
:判断栈是否为空,空栈时length
为 0。StackLength
:返回栈的当前长度,即栈中的元素数量。GetTop
:获取栈顶元素,栈顶元素通过参数e
返回。Push
:将元素入栈,分配新的栈节点,将其放在栈顶。Pop
:将栈顶元素出栈,并通过参数e
返回该元素,释放栈顶节点。DestroyStack
:销毁栈,释放所有节点的内存。ClearStack
:清空栈,实际操作和销毁栈一样,将所有节点释放掉。TraverseStack
:遍历栈并打印所有栈中的元素。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType; // 根据实际需要定义元素类型
#define OK 1
#define ERROR 0
typedef int Status;
typedef struct Node {
ElemType data; // 节点存储的数据
struct Node *next; // 指向下一个节点的指针
} StackNode;
typedef struct {
StackNode *top; // 指向栈顶节点的指针
int length; // 栈中元素的数量
} LinkStack;
// 初始化栈
Status InitStack(LinkStack &S) {
S.top = NULL;
S.length = 0;
return OK;
}
// 判断栈是否为空
Status StackEmpty(LinkStack S) {
return S.length == 0 ? OK : ERROR;
}
// 获取栈的长度
int StackLength(LinkStack S) {
return S.length;
}
// 获取栈顶元素
Status GetTop(LinkStack S, ElemType &e) {
if (StackEmpty(S) == OK) return ERROR; // 栈空
e = S.top->data; // 栈顶元素
return OK;
}
// 入栈操作
Status Push(LinkStack &S, ElemType e) {
StackNode *newNode = (StackNode *)malloc(sizeof(StackNode));
if (!newNode) return ERROR; // 分配失败
newNode->data = e;
newNode->next = S.top; // 新节点指向当前栈顶节点
S.top = newNode; // 栈顶指针指向新节点
S.length++; // 栈长度增加
return OK;
}
// 出栈操作
Status Pop(LinkStack &S, ElemType &e) {
if (StackEmpty(S) == OK) return ERROR; // 栈空
StackNode *temp = S.top; // 暂存栈顶节点
e = temp->data; // 取出栈顶元素
S.top = S.top->next; // 栈顶指针指向下一个节点
free(temp); // 释放原栈顶节点
S.length--; // 栈长度减少
return OK;
}
// 销毁栈
Status DestroyStack(LinkStack &S) {
StackNode *current = S.top;
while (current) {
StackNode *temp = current;
current = current->next;
free(temp); // 逐个释放节点
}
S.top = NULL;
S.length = 0;
return OK;
}
// 清空栈
Status ClearStack(LinkStack &S) {
DestroyStack(S); // 清空栈和销毁栈是相同的操作
return OK;
}
// 遍历栈并打印栈中的所有元素
void TraverseStack(LinkStack S) {
StackNode *current = S.top;
printf("Stack elements: ");
while (current) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
int main() {
LinkStack S;
ElemType e;
// 初始化栈
if (InitStack(S) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 10; i++) {
if (Push(S, i) == OK) {
printf("Element %d pushed onto stack.\n", i);
}
}
// 获取栈顶元素
if (GetTop(S, e) == OK) {
printf("Top element: %d\n", e);
}
// 遍历栈
TraverseStack(S);
// 出栈操作
while (Pop(S, e) == OK) {
printf("Element %d popped from stack.\n", e);
}
// 清空栈
ClearStack(S);
// 销毁栈
DestroyStack(S);
return 0;
}
12.带有扩展属性的顺序栈
typedef struct {
ElemType *elem; // 动态分配的数组基址
int top; // 栈顶位置,指向栈顶元素的下一个位置
int size; // 当前栈的容量
int max_size; // 栈的最大容量
int min_size; // 栈的最小容量
} SqStack_Extended;
特点
这种顺序栈除了基本的栈功能外,还可以添加额外的属性,例如栈的最大容量、栈的最小容量等。
常见操作接口
InitStack
:初始化栈,分配初始的存储空间,并设置top
为 0,指定栈的最大容量和最小容量。StackEmpty
:判断栈是否为空,空栈时top
为 0。StackLength
:返回栈的当前长度,即栈中的元素数量。GetTop
:获取栈顶元素,栈顶元素通过参数e
返回。ExpandStack
:扩容操作,当栈满时,容量加倍,确保容量不超过最大限制。ShrinkStack
:缩容操作,当栈使用量低于容量的四分之一时,将容量减半,但不低于最小限制。Push
:将元素入栈,如果栈满则自动扩容。Pop
:将栈顶元素出栈,并通过参数e
返回该元素,出栈后可能自动缩容。DestroyStack
:销毁栈,释放所有分配的内存。ClearStack
:清空栈,将top
重置为 0。TraverseStack
:遍历栈并打印所有栈中的元素。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType; // 根据实际需要定义元素类型
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define UNDERFLOW -3
typedef int Status;
typedef struct {
ElemType *elem; // 动态分配的数组基址
int top; // 栈顶位置,指向栈顶元素的下一个位置
int size; // 当前栈的容量
int max_size; // 栈的最大容量
int min_size; // 栈的最小容量
} SqStack_Extended;
// 初始化栈
Status InitStack(SqStack_Extended &S, int initial_size, int max_size, int min_size) {
if (initial_size < min_size || initial_size > max_size) return ERROR;
S.elem = (ElemType *)malloc(initial_size * sizeof(ElemType));
if (!S.elem) return OVERFLOW; // 分配失败
S.top = 0;
S.size = initial_size;
S.max_size = max_size;
S.min_size = min_size;
return OK;
}
// 判断栈是否为空
Status StackEmpty(SqStack_Extended S) {
return S.top == 0 ? OK : ERROR;
}
// 获取栈的长度
int StackLength(SqStack_Extended S) {
return S.top;
}
// 获取栈顶元素
Status GetTop(SqStack_Extended S, ElemType &e) {
if (StackEmpty(S) == OK) return ERROR; // 栈空
e = S.elem[S.top - 1]; // 栈顶元素
return OK;
}
// 扩容操作
Status ExpandStack(SqStack_Extended &S) {
int new_size = S.size * 2;
if (new_size > S.max_size) return OVERFLOW; // 超过最大容量
ElemType *newbase = (ElemType *)realloc(S.elem, new_size * sizeof(ElemType));
if (!newbase) return OVERFLOW; // 分配失败
S.elem = newbase;
S.size = new_size;
return OK;
}
// 缩容操作
Status ShrinkStack(SqStack_Extended &S) {
if (S.size <= S.min_size) return ERROR; // 已经是最小容量
int new_size = S.size / 2;
if (new_size < S.min_size) new_size = S.min_size;
ElemType *newbase = (ElemType *)realloc(S.elem, new_size * sizeof(ElemType));
if (!newbase) return OVERFLOW; // 分配失败
S.elem = newbase;
S.size = new_size;
return OK;
}
// 入栈操作
Status Push(SqStack_Extended &S, ElemType e) {
if (S.top >= S.size) { // 栈满
if (ExpandStack(S) != OK) { // 扩容失败返回错误
return OVERFLOW;
}
}
S.elem[S.top++] = e; // 元素入栈
return OK;
}
// 出栈操作
Status Pop(SqStack_Extended &S, ElemType &e) {
if (StackEmpty(S) == OK) return ERROR; // 栈空
e = S.elem[--S.top]; // 栈顶元素出栈
// 自动缩容
if (S.top <= S.size / 4 && S.size > S.min_size) {
ShrinkStack(S);
}
return OK;
}
// 销毁栈
Status DestroyStack(SqStack_Extended &S) {
if (S.elem) {
free(S.elem);
S.elem = NULL;
}
S.top = 0;
S.size = 0;
S.max_size = 0;
S.min_size = 0;
return OK;
}
// 清空栈
Status ClearStack(SqStack_Extended &S) {
S.top = 0;
return OK;
}
// 遍历栈并打印栈中的所有元素
void TraverseStack(SqStack_Extended S) {
printf("Stack elements: ");
for (int i = 0; i < S.top; i++) {
printf("%d ", S.elem[i]);
}
printf("\n");
}
int main() {
SqStack_Extended S;
ElemType e;
// 初始化栈
if (InitStack(S, 5, 20, 5) == OK) {
printf("Stack initialized successfully.\n");
}
// 入栈操作
for (int i = 0; i < 15; i++) {
if (Push(S, i) == OK) {
printf("Element %d pushed onto stack.\n", i);
}
}
// 获取栈顶元素
if (GetTop(S, e) == OK) {
printf("Top element: %d\n", e);
}
// 遍历栈
TraverseStack(S);
// 出栈操作
while (Pop(S, e) == OK) {
printf("Element %d popped from stack.\n", e);
}
// 清空栈
ClearStack(S);
// 销毁栈
DestroyStack(S);
return 0;
}
以上就是一些顺序栈的表示和实现,不同的顺序栈要放在合适的地方使用,确保代码的正确运行。