栈的概念
栈(Stack):是限制在表的一端进行插入和删除操作的线性表。又称为后进先出LIFO (Last In First Out)或先进后出FILO (First In Last Out)线性表。
栈顶(Top):允许进行插入、删除操作的一端,又称为表尾。用栈顶指针(top)来指示栈顶元素。
栈底(Bottom):是固定端,又称为表头。
空栈:当表中没有元素时称为空栈。
设栈S=(a1,a2,…an),则a1称为栈底元素,an为栈顶元素,如图所示。
栈中元素按a1,a2,…an的次序进栈,退栈的第一个元素应为栈顶元素。即栈的修改是按后进先出的原则进行的。
栈的顺序存储结构简称为顺序栈,和线性表相类似,用一维数组来存储栈。根据数组是否可以根据需要增大,又可分为静态顺序栈和动态顺序栈。
静态顺序栈实现简单,但不能根据需要增大栈的存储空间;
动态顺序栈可以根据需要增大栈的存储空间,但实现稍为复杂。
栈的链式表示:
#include <stdio.h>
#include <stdlib.h>
#ifndef LinkStack_h__
#define LinkStack_h__
typedef int datatype;
typedef struct _Stack
{
datatype num;
struct _Stack *next;
}STACK;
//入栈
void PushElem(STACK **Stack, int value);
//弹栈
void PopElem(STACK **Stack, STACK *Result);
//取栈顶元素
STACK *TopElem(STACK *Stack);
//清空栈
void ClearStack(STACK **Stack);
//输出所有元素
void ShowNum(STACK *Stack);
#endif // LinkStack_h__
以上代码的实现:
#include "LinkStack.h"
//入栈
void PushElem(STACK **Stack, int value)
{
STACK *pNew = (STACK *)malloc(sizeof(STACK));
pNew->num = value;
pNew->next = NULL;
if (NULL == (*Stack))
{
(*Stack) = pNew;
}
else
{
STACK *pPos = (*Stack);
while (pPos->next != NULL)
{
pPos = pPos->next;
}
pPos->next = pNew;
}
}
//弹栈
void PopElem(STACK **Stack, STACK *Result)
{
if (NULL == (*Stack))//没有元素
{
return;
}
else
{
if (NULL == (*Stack)->next)//只有一个元素
{
Result->num = (*Stack)->num;
free(*Stack);
(*Stack) = NULL;
}
else//两个及以上元素
{
STACK *pTemp = (*Stack);
while (pTemp->next->next != NULL)
{
pTemp = pTemp->next;
}
Result->num = (pTemp->next)->num;
free(pTemp->next);
pTemp->next = NULL;
}
}
}
//取栈顶元素
STACK *TopElem(STACK *Stack)
{
STACK *pPos = Stack;
while (pPos->next != NULL)
{
pPos = pPos->next;
}
return pPos;
}
//清空栈
void ClearStack(STACK **Stack)
{
while ((*Stack) != NULL)
{
if (NULL == (*Stack))
{
return;
}
if (NULL == (*Stack)->next)
{
free((*Stack));
(*Stack) = NULL;
}
else
{
STACK *pTemp1 = (*Stack);
STACK *pTemp2 = NULL;
while (pTemp1->next != NULL)
{
pTemp2 = pTemp1->next;
pTemp1->next = pTemp2->next;
free(pTemp2);
}
}
}
}
//输出所有元素
void ShowNum(STACK *Stack)
{
if (NULL == Stack)
{
return;
}
else
{
ShowNum(Stack->next);
printf("%d\n", Stack->num);
}
}
测试:
#include "LinkStack.h"
int main(void)
{
STACK *sHead = NULL;
PushElem(&sHead, 1);
PushElem(&sHead, 2);
PushElem(&sHead, 3);
PushElem(&sHead, 4);
PushElem(&sHead, 5);
ShowNum(sHead);
/*
STACK *pRes = (STACK *)malloc(sizeof(STACK));
printf("弹出栈内的元素为:\n");
while (sHead != NULL)
{
PopElem(&sHead, pRes);
printf("%d\n", pRes->num);
}
*/
/*
STACK *pRes = (STACK *)malloc(sizeof(STACK));
pRes = TopElem(sHead);
printf("栈顶的元素为:%d\n", pRes->num);
*/
/*
printf("清空后的栈为:\n");
ClearStack(&sHead);
ShowNum(sHead);
*/
return 0;
}