1.基本概念
定义:限定只能在固定一端进行插入和删除操作的线性表。特点:后进先出。
允许进行插入和删除操作的一端称为栈顶,另一端称为栈底。
作用:可以完成从输入数据序列到某些输出数据序列的转换
(1)顺序堆栈
顺序堆栈:顺序存储结构的堆栈。
顺序栈的存储结构:利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素.
操作实现:
//定义
typedef struct
{
DataType stack[MaxStackSize];
int top;
} SeqStack;
//初始化StackInitiate(S)
void StackInitiate(SeqStack *S)
{
S->top = 0;
}
//非空否StackNotEmpty(S)
int StackNotEmpty(SeqStack S)
{
if (S.top <= 0)
return 0;
else
return 1;
}
//入栈StackPush(S, x)
int StackPush(SeqStack *S, DataType x)
{
if (S->top >= MaxStackSize)
{
printf("堆栈已满无法插入! \n");
return 0;
}
else
{
S->stack[S->top] = x;
S->top++;
return 1;
}
}
//出栈StackPop(S, d)
int StackPop(SeqStack *S, DataType *d)
{
if (S->top <= 0)
{
printf("堆栈已空无数据元素出栈! \n");
return 0;
}
else
{
S->top--;
*d = S->stack[S->top];
return 1;
}
}
//取栈顶数据元素StackTop(SeqStack S, DataType *d)
int StackTop(SeqStack S, DataType *d)
{
if (S.top <= 0)
{
printf("堆栈已空! \n");
return 0;
}
else
{
*d = S.stack[S.top - 1];
return 1;
}
}
(2).链式堆栈
链式堆栈:链式存储结构的堆栈。
链式栈的存储结构:它是以头指针为栈顶,在头指针处插入或删除,带头结点的链式堆栈结构.
链栈中每个结点由两个域构成:data域和next域,即数据域和指针域。
//定义
typedef struct snode
{
DataType data;
struct snode *next;
} LSNode;
//初始化StackInitiate(head)
void StackInitiate(LSNode **head)
{
*head = (LSNode *)malloc(sizeof(LSNode));
(*head)->next = NULL;
}
//非空否StackNotEmpty(head)
int StackNotEmpty(LSNode *head)
{
if (head->next == NULL)
return 0;
else
return 1;
}
//入栈StackPush(head, x)
int StackPush(LSNode *head, DataType x)
{
LSNode *p;
p = (LSNode *)malloc(sizeof(LSNode));
p->data = x;
p->next = head->next;
head->next = p;
return 1;
}
//出栈StackPop(head, *d)
int StackPop(LSNode *head, DataType *d)
{
LSNode *p = head->next;
if (p == NULL)
{
printf("堆栈已空出错!");
return 0;
}
head->next = p->next;
*d = p->data;
free(p);
return 1;
}
//取栈顶数据元素StackTop(head, d)
int StackTop(LSNode *head, DataType *d)
{
LSNode *p = head->next;
if (p == NULL)
{
printf("堆栈已空出错!");
return 0;
}
*d = p->data;
return 1;
}
//撤消动态申请空间Destroy(*head)
void Destroy(LSNode *head)
{
LSNode *p, *p1;
p = head;
while (p != NULL)
{
p1 = p;
p = p->next;
free(p1);
}
}
说明:
- 链栈的入栈、出栈操作就是栈顶的插入与删除操作,修改指针即可完成。
2)一般不会出现栈满情况;除非没有空间导致malloc分配失败。
3)采用链栈存储方式的优点是,当栈中元素个数变化较大,准确数字难以确定时,链栈较顺序堆栈方便。