前言:又到了更新博客的时间了,实际上我上周又没有多少笔记存货,但是数据结构的学习是当前的重点,一直拖延不是好的习惯,没有条件,那就强行“创造”条件吧。本篇博客主要内容来自《数据结构与算法分析》C语言描述,下周一定要整点“干货”了;下面开始:
一、栈模型及其基本概念
- 栈(stack):是限定仅在表尾进行插入或删除的线性表;表尾端有其特殊的含义,被称为栈底,相应的,表头就被称为栈顶;对栈的基本操作有Push(进栈)和Pop(出栈),前者相当于插入,后者相当于删除,都是在栈顶进行的。
- 栈有时又被叫做LIFO(last in first out)表,即后进先出线性表;一般栈的模型是:存在某个元素位于栈顶,而该元素是唯一的可见元素;
- 我个人的理解是:把栈模型看成弹夹模型,进栈是把子弹元素压入,出栈是把子弹元素弹出,都在顶部操作,遵循后压入的子弹可以先拿出来的原则。
二、栈的链表实现
1、声明部分
/* 栈的链表实现声明 */
#ifndef _Stack_h
#define _Stack_h
typedef struct Node
{
ElemType Elem;
PtrToNode Next;
}Node;
typedef struct Node *PtrToNode; //自定义指向Node的数据类型PtrToNode
typedef PtrToNode Stack; //等价于typedef struct Node *Stack,仔细品
int IsEmpty(Stack S);
Stack CreateStack(void);
void MakeEmpty( Stack S);
void Push(ElemType X,Stack S);
ElemType Top(Stack S);
void Pop(Stack S);
#endif
2、测试栈是否为空(IsEmpty)
int
IsEmpty(Stack S)
{
return S->Next == NULL;与测试空表的方式相同
}
3、创建一个栈(CreateStack)
- 创建一个头结点,MakeEmpty设置Next指针指向NULL;
/* 创建一个空表 */
Stack
CreateStack(void)
{
Stack S;
S = malloc(sizeof( Node));
if(s == NULL)
printf("Out of space");
S->Next == NULL;
MakeEmpty(S);
return S;
}
void
MakeEmpty(Stack S)
{
if(S ==NULL)
printf("Must use CreateStack first");
else
while(!IsEmpty(S))
Pop(S);
}
4、进栈(Push)
- Push是通过向链表前端进行插入而实现的,表的前端作为栈顶;
/* 进栈操作实现 */
void
Push(ElemType X,Stack S)
{
PtrToNode TmpCell;
TmpCell = malloc(sizeof(Node));
if(TmpCell ==NULL)
printf("Out of space");
else
{
TmpCell->Elem = X;
TmpCell->Next = S->Next;
S->Next = TmpCell;
}
}
5、出栈Pop
- Pop是通过删除表前端元素而实现的,表的前端作为栈顶;
/* 出栈操作实现 */
void
Pop(Stack S)
{
PtrToNode FirstCell;
if(IsEmpty(S))
printf("Empty stack");
else
{
FirstCell = S->Next;
S->Next = S->Nest->Next;
free(FirstCell);
}
}
5、检查表第一位的元素(Top)
/* 检查表第一位的元素 */
ElemType
Top(Stack S)
{
if(!IsEmpty(S))
return S->Next->Elem;
else
{
printf("Empty stack");
return 0;
}
}
这里要注意:为什么Stack的前面不用加*呢?
typedef struct Node *PtrToNode; //自定义指向Node的数据类型PtrToNode
typedef PtrToNode Stack; //等价于typedef struct Node *Stack,仔细品
这两段代码要理解清楚,这里是*PtrToNode通过自定义数据类型用Stack表示了