数据结构学习:栈与链栈
线性表是具有相同数据类型的n(n≥0)个数据元素的有限序列,其中n为表长,当n = 0 时,线性表是一个空表。
栈的定义
栈(Stack)是只允许在一端进行插入或删除操作的线性表
InitList(&L):初始化表。构造一个空的线性表L,分配内存空间。
DestroyList(&L):销毁操作。销毁线性表,并释放线性表L所占用的内存空间。
ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。
ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。
LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。
GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。
其他常用操作:
Length(L):求表长。返回线性表L的长度,即L中数据元素的个数。
PrintList(L):输出操作。按前后顺序输出线性表L的所有元素值。
Empty(L):判空操作。若L为空表,则返回true,否则返回false。
Push(&S,x):进栈,若栈S未满,则将x加入使之成为新栈顶。
Pop(&S,&x):出栈,若栈S非空,则弹出栈顶元素,并用x返回。
GetTop(S, &x):读栈顶元素。若栈 S 非空,则用 x 返回栈顶元素
出栈序列总数有:
栈的定义与基本操作
定义一个静态栈
#define MaxSize 10 //定义栈内元素的个数
typedef struct
{
ElemType data[MaxSize]; //静态数组存放栈中的元素
int top; //栈订指针
}SqStack //sequence stack 顺序栈
//初始化栈
void InitStack(SqStack &S)
{
s.top = -1; //初始化栈顶指针
}
//判断栈是否为空
bool EmptyStack(SqStack S)
{
if(S.top == -1)//是否是-1需要看初始化时的栈顶指针
return true;
else
return false;
}
//新元素入栈
bool Push(SqStack &S,ElemType x)
{
if(S.top == MaxSize - 1)
return false; //栈满
S.top ++; //栈顶指针加一
S.data[S.top] = x; //新元素入栈
return true;
}
//元素出栈
bool Push(SqStack &S,ElemType &x)//出栈对元素采用&操作
{
if(S.top == -1)
return false; //栈空
x = S.data[S.top]; //元素出栈
S.top --; //栈顶指针减一
return true;
}
//读取栈顶元素
bool Push(SqStack S,ElemType &x)//读取对栈不需要采用&操作
{
if(S.top == -1)
return false; //栈空
x = S.data[S.top]; //栈顶元素赋值
return true;
}
共享栈
原理:一个从下往上存储,一个从上往下存储
#define MaxSize 10 //定义栈内元素的个数
typedef struct
{
ElemType data[MaxSize]; //静态数组存放栈中的元素
int top0; //一号栈栈顶指针
int top1; //二号栈栈顶指针
}ShStack //sequence stack 顺序栈
//初始化共享栈
void InitStack(ShStack &S)
{
//初始化两个共享栈顶指针
S.top0 = -1;
S.top1 = MaxSize;
}
共享栈的栈满条件为top0 + 1 == top1
链栈的定义和基础操作
typedef struct LinkNode
{
ElemType data;
struct LinkNode *next;
}LinkNode; //链栈结点定义
typedef struct
{
LinkNode *top;
}LinkStack;//定义链栈头指针
//初始化链栈
void InitStack(LinkStack &S)
{
S.top = (LinkNode *)malloc(sizeof(LinkNode));
S.top->next = NULL;
}
//链栈指针由栈顶指向栈底
//新元素入栈
bool Push(LinkStack &S,ElemType x)
{
LinkNode *q = (LinkNode *)malloc(sizeof(LinkNode));
q->data = x;
q->next = S.top->next;//链栈插入新元素
S.top = q; //栈顶指针指向新节点
return true;
}
//元素出栈
bool Pop(LinkStack &S,ElemType &x)//出栈对元素采用&操作
{
if(S.top == NULL)
return false; //栈空
LinkNode *q = (LinkNode *)malloc(sizeof(LinkNode));
q = S.top->next;
x = q->data; //元素出栈
S.top->next = q->next; //栈顶指针后移
free(q);
return true;
}
bool EmptyStack(LinkStack S)
{
if(S.top->next == NULL)
return true;
else
return false;
}
括号与栈的关系
遇到左括号就入栈,遇到右括号,就 “消耗”一个左括号(出栈)