1.栈的特点是 先进后出 。
2.链式栈没有限定容量(MAXSIZE),也就是栈可以容纳的元素取决于内存分配。对特定的程序,用不同的方法实现,如还可以用数组式的栈。
3.实际上是一个没有头节点的链表,只不过对操作做了限定
4.把栈顶元素定为 链表的第一个节点,也就是头指针指向的结点为栈顶,这样在压栈和出栈是方便操作。
5.下面是对链式栈的实现,并写了一个驱动程序进行测试。
6..驱动程序说明:输入仅由 ' ( ' 和 ' ) ' 组成的 字符组合,判断 括号是否匹配。
如 ( ) 和 ()() 和 (()) 都是匹配的。
7.注意,在dos命令行界面下,EOF是用键盘的ctrl + z 组合 模拟的。另外,输入EOF需要在新的一行输入.
# include <stdio.h>
# include <stdlib.h>
# include <malloc.h>
# include <assert.h>
typedef char DataType; /* 对特定程序要求作修改为相应的数据类型*/
typedef struct stack
{
DataType data;
struct stack*next;
}SNode;
typedef SNode* Stack;
/************ADT接口声明******************/
void InitStack(Stack*pf);
int Push(Stack*pf,DataType tdata);
int Pop(Stack*pf);
int GetTop(Stack*pf,DataType *pdata);
unsigned int StackLength(Stack*pf);
int StackIsEmpty(Stack*pf);
void DestroyStack(Stack*pf);
/*****************END********************/
/*
驱动测试程序说明:从控制台输入 仅有 '(' 和 ')' 2个字符
检测左右括号是否匹配,如() ,(()) 都为匹配,否则不匹配
*/
int main (void)
{
Stack test;
InitStack(&test);
char current;
char previous;
while((current=getchar())!=EOF )
{
//putchar(current);
if(current=='\n')//消除输入完毕后按下回车键在缓冲区产生的'\n'字符的影响
continue;
assert(Push(&test,current)); //入栈
if(1!=StackLength(&test)) //当栈中只有一个元素时,没必要比较匹配
if(previous=='(' && current==')')
{
Pop(&test);
Pop(&test);
}
GetTop(&test,&previous); //获取栈顶元素,为下一次匹配准备
}
printf("\n");
if(StackIsEmpty(&test)) //经过循环匹配后栈空了,则说明匹配
puts("符号匹配!");
else
puts("符号不匹配!");
return 0;
}
void InitStack(Stack*pf)
{
*pf=NULL;
return ;
}
int Push(Stack*pf,DataType tdata)
{
SNode*pnew;
pnew=(SNode*)malloc(sizeof(SNode));
if(pnew==NULL)
return 0;
pnew->data=tdata;
pnew->next=*pf;
*pf=pnew; //新进栈元素成为栈顶
return 1;
}
int Pop(Stack*pf)
{
SNode*pt;
if(*pf==NULL) //如果是空栈
return 0;
pt=*pf; //取出第一个节点地址
*pf=(*pf)->next; //栈顶指针下移
free(pt);
return 1;
}
int GetTop(Stack*pf,DataType *pdata)
{
if(*pf==NULL) //如果是空栈
return 0;
*pdata=(*pf)->data; //取出栈顶数据
return 1;
}
unsigned int StackLength(Stack*pf)
{
SNode*p=*pf; //取出第一个节点地址
unsigned count = 0;
while(p!=NULL)
{
p=p->next;
++count;
}
return count;
}
int StackIsEmpty(Stack*pf)
{
return (*pf)==NULL;
}
void DestroyStack(Stack*pf)
{
SNode*p=(*pf); //取出第一个节点地址
SNode*pt;
while(p!=NULL)
{
pt=p;
p=p->next;
free(pt);
}
return ;
}