栈
来源:互联网 发布:身份证复印件软件下载 编辑:程序博客网 时间:2024/05/22 01:36
栈,也是线性表(n个元素e1,e2….en组成的有限序列),顺序表,链表都是线性表,不过栈只能在一端(栈顶)插入和删除,称为”入栈”和“出栈”,(早期教材叫做“压栈”和“弹栈”);这就好比弹夹装子弹,栈
又分为顺序栈和链栈
1:顺序栈
1)结构
typedef struct sStack { ElementType data[MAXLEN]; //栈元素 int top; //栈顶指示器 }seqStack;
栈顶指示器是为了表示栈顶元素的位置,规定空栈的栈顶指示器为-1
2) 初始化栈
void InitialStack(seqStack &s){ s.top=-1;}
3)判断栈是否为空
bool StackEmpty(seqStack s){ if(-1==s.top) return true; return false;}
4)取栈顶元素
void StackTop(seqStack s,ElementType &x){ if(StackEmpty(s)) cout<<"栈空,不能取栈顶元素\n"; x=S.data[s.top];}
5) 判断栈满
bool StackFull(seqStack s){ if(MAXLEN-1==s.top) return true; return false; }
6)入栈
void PushStack(seqStack &s,ElementType x){ if(StackFull(s)) cout<<"栈满,不能入栈\n"; s.top++; s.data[s.top]=x;}
7)出栈
void PopStack(seqStack &s,ElementType x){ if(StackEmpty(s)) cout<<"栈空,不能出栈\n"; x=s.data[s.top]; s.top--;}
2:链栈
链栈即采用链式存储,由于是一端操作,而且栈顶指针每次入栈出栈后都要改变,故不用带头节点
1)结构
typedef struct lsNode{ ElementType data; struct lsNode *next;}sNode;
2)初始化
void InitialStack(sNode *&top){ top=NULL;}
3)入栈
void PushStack(sNode *&top,ElementType x){ sNode *s=new sNode; s->data=x; s->next=top; //链表一般不用考虑栈满 top=s;}
4)出栈
void PopStack(sNode *&top,ElememtType x) { if(NULL==top) cout<<"栈空,不能出栈\n"; sNode *u; x=top.data; u=top; top=top->next; delete u; u=NULL; }
顺便说一下栈就地逆置吧,就是将栈各节点的后驱指针倒置指向前驱的节点,e1变为最后一个节点,最后一个节点变为第一个节点
void Reveser(sNode &top){ node *p=NULL; node *u; while(top!=NULL) { u=top; //将u指向待分离的表头节点,u和top指向了未逆置部分的第一个节点 top=top->next; //未逆置部分表头后移一位 u->next=p; //本来这是第一个节点,指向p所指向节点后就为null了,显然符合逻辑 p=u; //以逆置部分的表头指针指向新分离出的节点 } top=p; //原来的表头指针指向心的镖头指针}
0 0