数据结构--栈(C语言实现)
一、栈的基本概念
1.栈的定义
栈是一种只能在一端进行插入或删除的线性表。其中允许进行插入或删除操作的一端称为栈顶(top)。栈的插入和删除操作一般称作入栈和出栈。
2.栈的特点
先进后出
3.栈的存储结构
顺序栈和链式栈
注意:链式栈通常采用单链表实现,并规定所有的操作都是在单链表的表头进行的。而且对于带头结点和不带头结点的链栈,具体的实现会有所不同。
4.栈的数学性质
当n个元素以某种顺序进栈,并且可在任意时刻出栈(满足先进后出的前提),所获得的元素排列的数目N恰好满足:
\[N=\frac{1}{n+1} \times C_{2n}^n \]二、结构体的定义
1.顺序栈
typedef struct
{
int data[maxSize]; //存放栈中元素,maxSize是已经定义的常量
int top; //栈顶指针
}SqStack;
2.链栈结点定义
typedef struct LNode
{
int data; //数据域
struct LNode *next; //指针域
}LNode;
三、顺序栈
1.顺序栈的要素
(1)几个状态
1)栈空状态
st.top == -1。(可能会出现st.top == 0的情况,具体问题具体分析)
2)栈满状态
st.top == maxSize-1。
3)非法状态
上溢或下溢
(2)两个操作
1)元素进栈。
++(st.top);
st.data[st.top]=x;
2)元素出栈
x=st.data[s.top];
--s.top;
2.初始化栈
void initStack(SqStack &st)
{
st.top=-1; //只需将栈顶指针设为-1
}
3.判空
int isEmpty(SqStack st)
{
if(st.top==-1)
{
return 1;
}
else
{
return 0;
}
}
4.进栈
int Push(SqStack &st,int x)
{
if(st.top==maxSize-1) //判断是否栈满
{
return 0;
}
++(st.top); // 先移动指针,再进栈
st.data[st.top]=x;
return 1;
}
5.出栈
int Pop(SqStack &st,int &x)
{
if(st.top==-1) //判断是否为空
{
return 0;
}
x=st.data[s.top]; //先取出元素,再进栈
--st.top;
}
四、链栈
1.链栈的要素
(1)两个状态
1)栈空状态
lst->next==NULL
2)栈满状态
不存在
(2)两个操作
1)进栈(带头结点)
p->next=lst->next; lst->next=p;//其实就是头插法建立单链表中的插入操作
2)出栈
p=lst->next;x=p->data;lst->next=p->next;free(p);//其实就是带头结点的单链表的删除操作
2.初始化
void initStack(LNode *&lst) //lst要改变,采用引用型,&
{
lst=(LNode*)malloc(sizeof(LNode));//制造一个头结点
lst->next=NULL;
}
3.判空
int isEmpty(LNode *lst)
{
if(lst->next==NULL)
{
return 1;
}
else
{
return 0;
}
}
4.进栈
void Push(LNode*lst,int x)
{
LNode *p;
p=(LNode*)malloc(sizeof(LNode));
p->next=NULL;//每当申请新结点的时候,将指针域设置为NULL,可以避免一些错误
/*以下就是链表的头插法*/
p->data=x;
p->next=lst->next;
lst->next=p;
}
5.出栈
int Pop(LNode*&lst,int &x)
{
LNode *p;
if(lst->next==NULL)
{
return 0;
}
/*以下就是单链表的删除操作*/
p=lst->next;
x=p->data;
lst->next=p->next;
free(p);
return 1;
}