- 栈作为一种限定性线性表,即将线性表的插入和删除操作限制为仅在表的一端进行。
- 通常将表中允许进行插入、删除操作的一端称为栈顶,栈顶的当前位置是动态变化的,它由一个称为栈顶指针的位置指示器来指示;将表的另一端称为栈底。
- 当栈中没有元素时称为空栈;栈的插入操作称为入栈,栈的删除操作称为出栈。
一、顺序栈
1.1 算法思想
顺序栈是用顺序存储结构实现的栈,即利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。同时由于栈操作的特殊性,还必须附设一个栈顶指针top来动态地指示栈顶元素在顺序栈中的位置。通常用 top=-1 来表示空栈。
1.2 算法实现
/* 初始化顺序栈 */
void InitStack(StackPtr *S) {
(*S)->top = -1;
}
/* 压栈操作 */
bool Push(StackPtr S, StackElementType x) {
if (IsFull(S)) return false;
/* 栈顶指针先加加,再压入新元素 */
S->elem[++S->top] = x;
return true;
}
/* 读取栈顶元素 */
bool GetTop(StackPtr S, StackElementType *x) {
if (IsEmpty(S)) return false;
/* 将栈顶元素存放到x所指向的变量中 */
*x = S->elem[S->top];
return true;
}
/* 出栈操作 */
bool Pop(StackPtr S, StackElementType *x) {
if (IsEmpty(S)) return false;
/* 先取出栈顶元素,栈顶指针再减减 */
*x = S->elem[S->top];
--S->top;
return true;
}
/* 清空操作 */
void ClearStack(StackPtr S) {
InitStack(&S);
}
/* 判空操作 */
bool IsEmpty(StackPtr S) {
return S->top == -1; /* 妙啊! */
}
/* 判满操作 */
bool IsFull(StackPtr S) {
return S->top == Stack_Size - 1; /* 妙啊! */
}
二、链栈
2.1 算法思想
链栈即采用链表作为存储结构实现的栈。为便于操作,这里采用带头结点的单链表实现栈。由于栈的插入和删除操作仅限制在表头位置进行,所以链表的表头指针就作为栈顶指针。
若 top->next == NULL,则代表栈空。
采用链栈不必预先估计栈的最大容量,只要系统有可用空间,链栈就不会出现溢出。
2.2 算法实现
/* 初始化链栈 */
void InitStack(StackPtr *S) {
/* 生成头结点 */
(*S) = (StackPtr)malloc(sizeof(LinkStackNode));
(*S)->next = NULL;
}
/* 压栈操作 */
bool Push(StackPtr S, StackElementType x) {
/* 生成新结点 */
LinkStackNodePtr temp = (LinkStackNodePtr)malloc(sizeof(LinkStackNode));
if (temp == NULL) return false;
/* 头插法 */
temp->data = x;
temp->next = S->next;
S->next = temp;
return true;
}
/* 读取栈顶元素 */
bool GetTop(StackPtr S, StackElementType *x) {
if (IsEmpty(S)) return false;
*x = S->next->data;
return true;
}
/* 出栈操作 */
bool Pop(StackPtr S, StackElementType *x) {
/* temp指向链栈中的第一个结点 */
LinkStackNodePtr temp = S->next;
/* 判断是否为空栈 */
/* 顺序栈判断条件:if (IsEmpty(S)) return false; */
if (temp == NULL) return false;
/* 将删除的元素存放到x所指向的变量中 */
*x = temp->data;
S->next = temp->next;
free(temp);
return true;
}
/* 清空操作 */
void ClearStack(StackPtr S) {
LinkStackNodePtr p = S, q;
/* p在前,q在后 */
while (p != NULL) {
q = p;
p = p->next;
free(q);
}
}
/* 判空操作 */
bool IsEmpty(StackPtr S) {
/*
if (S->next == NULL)
return true;
else
return false;
*/
return S->next == NULL;
}
/* 判满操作 */
bool IsFull(StackPtr S) {
return false;
}