栈的顺序表实现
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 1024
using namespace std;
typedef int Elemtype;
typedef struct {
Elemtype data[MAXSIZE];
int top;
}Seqstack;
void initSeqstack(Seqstack &s){
s.top=-1;
}
int stackEmpty(Seqstack &s){
return s.top==-1;
}
int SeqstackPush(Seqstack &s,Elemtype e){
if (s.top>=MAXSIZE-1)
return 0;
else {
s.top++;
s.data[s.top]=e;
return 1;
}
}
int SeqstackPop(Seqstack &s,Elemtype &e){
if (s.top==-1)
return 0;
else {
e=s.data[s.top];
s.top--;
return 1;
}
}
void getTop(Seqstack &s,Elemtype &e){
e=s.data[s.top];
}
void displaySeqstack(Seqstack &s){
for (int i=0;i<=s.top;i++)
printf("%d ",s.data[i]);
printf ("\n");
}
int main()
{
Seqstack s;Elemtype e;
initSeqstack(s);
for (int i=1;i<6;i++)
SeqstackPush(s,i);
displaySeqstack(s);
getTop(s,e);
printf ("%d\n",e);
SeqstackPop(s,e);
displaySeqstack(s);
return 0;
}
严蔚敏版 栈的实现
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OVERFLOW -2
using namespace std;
typedef int Elemtype;
typedef struct {
Elemtype *base;
Elemtype *top;
int stacksize;
}Seqstack;
int initStack(Seqstack &s){
s.base=(Elemtype *)malloc(sizeof(Elemtype)*STACK_INIT_SIZE);
if (!s.base ) exit(OVERFLOW);//存储分配失败
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
return 1;
}
int stackEmpty(Seqstack &s){
return s.top==s.base;
}
int stackLength(Seqstack &s){
return s.top-s.base;
}
int SeqstackPush(Seqstack &s,Elemtype e){
if (s.top-s.base >=s.stacksize){
s.base=(Elemtype *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(Elemtype));
if (!s.base) exit(OVERFLOW);
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT;
//上溢后:
//1.分配存储空间给base指针 2、判断是否分配成功 3、top/stacksize重新修改正确
}
*s.top=e;
s.top++;//或者可以合成*s.top++=e,先赋值再++
return 1;
}
int SeqstackPop(Seqstack &s,Elemtype &e){
if(s.top==s.base){
printf ("null");
return 0;
}
s.top--;
e=*s.top;
return 1;
}
void getTop(Seqstack &s,Elemtype &e){
if (s.base!=s.top){
e=*--s.top;
}
}
void displaySeqstack(Seqstack &s){
for (int i=0;i<=s.top-s.base;i++)
printf("%d ",s.base[i]);
printf ("\n");
}
int main()
{
Seqstack s;
initStack(s);
for (int i=1;i<6;i++)
SeqstackPush(s,i);
displaySeqstack(s);
Elemtype e;
getTop(s,e);
printf ("%d\n",e);
SeqstackPop(s,e);
displaySeqstack(s);
return 0;
}
建立链栈
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define OVERFLOW -2
using namespace std;
typedef int Elemtype;
typedef struct node {
Elemtype data;
struct node *next;
}node,*linkstack;
void initLinkstack(linkstack &top){
top=NULL;//无头节点的链栈
}
int linkstackEmpty(linkstack &top){
return top==NULL;
}
int linkstackPush(linkstack &top,Elemtype e){
linkstack p=(linkstack )malloc (sizeof(node));
if (!p) exit(OVERFLOW);
p->data=e;
p->next=top;
top=p;
return 1;
}
int linkstackPop(linkstack &top,Elemtype &e){
e=top->data;
linkstack p=top;
top=top->next;
free(p);
return 1;
}
void getTop(linkstack &top,Elemtype &E){
E=top->data;
}
void displaylinkstack(linkstack &top){
linkstack p=top;
while (p){
printf ("%d ",p->data);
p=p->next;
}
printf ("\n");
}
int main()
{
linkstack top;
initLinkstack(top);
for (int i=1;i<6;i++)
linkstackPush(top,i);
displaylinkstack(top);
Elemtype e;
getTop(top,e);
printf ("%d\n",e);
linkstackPop(top,e);
displaylinkstack(top);
return 0;
}
栈的应用
1.数制转换:对于输入的非负十进制整数,打印输出与之等值的八进制数。
//算法3.1
void conversion(){
Seqstack s;
initSeqstack(s);
int n;
cout<<"请输入一个十进制数字"<<endl;
cin>>n;
while (n){
int r=n%8;
SeqstackPush(s,r);
n=n/8;
}
displaySeqstack(s);
}
2.括号匹配检验
只有【】()两种括号,检查括号是否是匹配的。
输入一个字符:
1、左括号:压栈
2、右括号:如果栈为空,则右括号多了,输出不匹配信息;如果栈不为空,取出栈顶元素进行配对,如果配对成功弹栈,如果不成功则输出括号不匹配信息。
字符输入结束:
如果栈不为空,左括号多了,输出不匹配信息;否则输出终于匹配信息!
int match(){
Seqstack s;
initSeqstack(s);
char c;Elemtype e;
scanf ("%c",&c);
while (c!='#'){
if (c=='['||c=='(')
SeqstackPush(s,c);
else if (c==']'||c==')'){
if (!stackEmpty(s)){
e=getTop(s);
if (e=='['&&c==']'||e=='('&&c==')'){
SeqstackPop(s,e);
}
}else
printf ("右括号太多了!\n");
}else
printf ("输入符号有误!\n");
scanf ("%c",&c);
}
if (!stackEmpty(s))
printf ("左括号太多!\n");
else
printf ("成功匹配");
}
3.行编辑程序
void lineEdit(){
Seqstack s;
initSeqstack(s);
char c;
cout<<"输入字符吧!\n"<<endl;
cin>>c;
while (c!='\n'){
switch (c){
case '#':SeqstackPop(s);break;
case '@':clearstack(s);break;
default:SeqstackPush(s,c);
}
c=getchar();
}
displaySeqstack(s);
}
顺序队列的基本实现
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 1024
using namespace std;
typedef int Elemtype;
typedef struct{
Elemtype data[MAXSIZE];
int rear,front;
}Seqqueue;
void initSeqqueue(Seqqueue &q){
q.rear=q.front=-1;
}
int emptySeqqueue(Seqqueue &q){
return q.rear==q.front;
}
int enSeqqueue(Seqqueue &q,Elemtype e){
//先判断是否栈满
if (q.rear-q.front>=MAXSIZE){
printf ("full!\n");
return 0;
}
q.rear++;
q.data[q.rear]=e;
return 1;
}
int deSeqqueue(Seqqueue &q,Elemtype &e){
if (emptySeqqueue(q)){
printf ("null!\n");
return 0;
}
q.front++;
e=q.data[q.front];
return 1;
}
Elemtype getFront(Seqqueue &q){
if (emptySeqqueue(q)){
printf ("null!\n");
}
else {
Elemtype e;
e=q.data[q.front++];
return e;
}
}
void display(Seqqueue &q){
if (emptySeqqueue(q)){
printf ("null!\n");
}
else {
int i=1+q.front;
while (i<=q.rear){
printf ("%d ",q.data[i]);
i++;
}
printf ("\n");
}
}
int main()
{
Seqqueue q;
initSeqqueue(q);
for (int i=1;i<6;i++)
enSeqqueue(q,i);
display(q);
Elemtype e;
deSeqqueue(q,e);
printf ("%d\n",e);
e=getFront(q);
printf ("%d\n",e);
return 0;
}
//1.用两个栈,一个s1,一个s2,来模拟一个队列。队列是先进先出,栈是先进后出,用两个栈模拟一个队列
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 1024
using namespace std;
//1.用两个栈,一个s1,一个s2,来模拟一个队列。队列是先进先出,栈是先进后出,用两个栈模拟一个队列
//2.一带头结点的循环链表表示队列,设计出队入队的算法。
//3.用一个数组建两个栈。建两个以上的栈最好用链栈,每一个都是一个栈。
//因为用数组建两个栈可以,不能建多个栈
//4.队列的题目已经上传。
typedef int Elemtype;
typedef struct {
Elemtype data[MAXSIZE];
int top;
}Seqstack;
void initSeqstack(Seqstack &s){
s.top=-1;
}
int isempty(Seqstack &s){
return s.top==-1;
}
int push(Seqstack &s,Elemtype e){
if (s.top>=MAXSIZE-1){
printf ("full\n");
return 0;
}
s.top++;
s.data[s.top]=e;
return 1;
}
int pop(Seqstack &s,Elemtype &e){
if (s.top==-1){
printf ("null\n");
return 0;
}
e=s.data[s.top];
s.top--;
return 1;
}
Elemtype gettop(Seqstack &s){
return s.data[s.top];
}
//入队,直接进1号栈;出队,先判断2号栈是否有元素,有元素就直接弹出栈顶即队首,如果2号栈没有元素,则将1号栈的元素顺序弹出并进2号栈。
typedef struct {
Seqstack s1;//数据输入栈
Seqstack s2;//数据缓存栈,便于先存放进去的元素先出来
}dulstack;
void initDulstack(dulstack &d){
initSeqstack(d.s1);
initSeqstack(d.s2);
}
int enterQueue(dulstack &d,Elemtype x){
Elemtype e;
if (isempty(d.s1)){
//如果S1栈为空,应当把S2栈中的元素全部弹出压入该栈
while (!isempty(d.s2)){
pop(d.s2,e);
push(d.s1,e);
}
}
push(d.s1,x);
return 1;
}
int deQueue(dulstack &d,Elemtype &x){
Elemtype e;
if (!isempty(d.s2)){
x=gettop(s2);
return 1;
}
while (!isempty(d.s1)){
pop(d.s1,e);
push(d.s2,e);
}
pop(d.s2,x);
return 1;
}
int isemptydulQueue(dulstack d){
return isempty(d.s1)&&isempty(d.s2);
}
int main()
{
dulstack d;
initDulstack(d);
Elemtype x;
scanf ("%d",&x);
while (x!=-999){
enterQueue(d,x);
scanf ("%d",&x);
}
while (!isemptydulQueue(d)){
deQueue(d,x);
printf ("%d ",x);
}
cout<<endl;
return 0;
}
//2.一带头结点的循环链表表示队列,设计出队入队的算法。
typedef int Elemtype;
typedef struct node {
Elemtype data;
struct node *next;
}node,*Queueptr;
typedef struct {
Queueptr front ;
Queueptr rear;
}linkQueue;
int initQueue(linkQueue &q){
Queueptr lq=(Queueptr)malloc(sizeof(node));
if (!lq) exit(OVERFLOW);
lq->next=NULL;
q.front=q.rear=lq;
}
int isempty(linkQueue q){
return q.front==q.rear;
}
int enterQueue(linkQueue &q,Elemtype e){
Queueptr p=(Queueptr)malloc(sizeof(node));
if (!p) exit(OVERFLOW);
p->data=e;
p->next=q.rear->next;
q.rear->next=p;
q.rear=p;
return 1;
}
int deQueue(linkQueue &q,Elemtype &e){
//出队依旧要判空,入队不需要判满了
if (q.rear==q.front){
printf("null\n");
return 0;
}
Queueptr p=q.front->next;
e=p->data;
q.front->next=p->next;
//这里要特别注意如果链表中唯一的元素要出队,尾指针必须要重新指向头结点,不然丢失该指针了
if (q.front->next==NULL){//或者q.rear==p;
q.rear=q.front;
}
free(p);
return 1;
}
int main()
{
linkQueue q;
initQueue(q);
Elemtype e;
scanf ("%d",&e);
while (e!=-999){
enterQueue(q,e);
scanf ("%d",&e);
}
while (!isempty(q)){
deQueue(q,e);
printf ("%d ",e);
}
cout<<endl;
return 0;
}
用两个队列建立一个栈
/两个队列模拟一个堆栈/
/队列A、B
入栈:将元素依次压入到非空的队列,第一个元素压倒对列A
出栈:把队列A的前n-1个元素倒到队列B,把第n个元素去掉。此时数据在B中,下次操作,则对B操作。
栈顶:把队列A的前n-1个元素倒到队列B,把第n个元素作为栈顶/
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 1024
#define OVERFLOW -2
using namespace std;
typedef int Elemtype;
typedef struct node {
Elemtype data;
struct node *next;
}node,*Queueptr;
typedef struct {
Queueptr front ;
Queueptr rear;
}linkQueue;
int initQueue(linkQueue &q){
Queueptr lq=(Queueptr)malloc(sizeof(node));
if (!lq) exit(OVERFLOW);
lq->next=NULL;
q.front=q.rear=lq;
}
int isempty(linkQueue q){
return q.front==q.rear;
}
int enterQueue(linkQueue &q,Elemtype e){
Queueptr p=(Queueptr)malloc(sizeof(node));
if (!p) exit(OVERFLOW);
p->data=e;
p->next=q.rear->next;
q.rear->next=p;
q.rear=p;
return 1;
}
int deQueue(linkQueue &q,Elemtype &e){
//出队依旧要判空,入队不需要判满了
if (q.rear==q.front){
printf("null\n");
return 0;
}
Queueptr p=q.front->next;
e=p->data;
q.front->next=p->next;
//这里要特别注意如果链表中唯一的元素要出队,尾指针必须要重新指向头结点,不然丢失该指针了
if (q.front->next==NULL){//或者q.rear==p;
q.rear=q.front;
}
free(p);
return 1;
}
int getlength(linkQueue &lq){
Queueptr p=lq.front->next;
int count=0;
while (p!=NULL){
count++;
p=p->next;
}
return count;
}
typedef struct {
linkQueue q1;
linkQueue q2;
}dulQueue;
void initDulQueue(dulQueue &dq){
initQueue(dq.q1);
initQueue(dq.q2);
}
int isemptyDul(dulQueue dq){
return isempty(dq.q1)&&isempty(dq.q2);
}
int pushDul(dulQueue &dp,Elemtype e){
if (isempty(dp.q2)){
enterQueue(dp.q1,e);
}
if (isempty(dp.q1)){
enterQueue(dp.q2,e);
}
return 1;
}
int popDul(dulQueue &dp,Elemtype &x){
Elemtype e;
if (isempty(dp.q2)){
int count=getlength(dp.q1);
for (int i=0;i<count-1;i++){
deQueue(dp.q1,e);
enterQueue(dp.q2,e);
}
if (isempty(dp.q1)){
//如果这时Q1弹出了最后一个元素
deQueue(dp.q2,x);
}else
deQueue(dp.q1,x);
return 1;
}
if (isempty(dp.q1)){
int count=getlength(dp.q2);
for (int i=0;i<count-1;i++){
deQueue(dp.q2,e);
enterQueue(dp.q1,e);
}
deQueue(dp.q2,x);
return 1;
}
}
int main()
{
dulQueue dq;
initDulQueue(dq);
Elemtype e;
scanf ("%d",&e);
while (e!=-999){
pushDul(dq,e);
scanf ("%d",&e);
}
while (!isemptyDul(dq)){
popDul(dq,e);
printf ("%d ",e);
}
cout<<endl;
return 0;
}
用一个数组建立两个栈
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 20
#define OVERFLOW -2
using namespace std;
typedef int Elemtype;
typedef struct {
Elemtype data[MAXSIZE];
int top[2];
}Seqstack;
void initSeqstack(Seqstack &s){
s.top[0]=-1;
s.top[1]=MAXSIZE;
}
int isempty(Seqstack s,int i){
if (i==0)
return s.top[i]==-1;
else
return s.top[i]==MAXSIZE;
}
int isfull(Seqstack s){
return s.top[0]+1==s.top[1];
}
int push(Seqstack &s,Elemtype e,int i){
//用int i来判断用户想要push进0栈还是1栈
if (isfull(s)){
printf("full!\n");
return 0;
}
if (i==0)
s.top[i]++;
else
s.top[i]--;
s.data[s.top[i]]=e;
return 1;
}
int pop(Seqstack &s,Elemtype &e,int i){
if (isempty(s,i)){
printf ("null\n");
return 0;
}
e=s.data[s.top[i]];
if (i==0)
s.top[i]--;
else
s.top[i]++;
return 1;
}
int main()
{
Seqstack s;
initSeqstack(s);
int x,i;
scanf ("%d %d",&x,&i);
while (x!=-999){
push(s,x,i);
scanf ("%d %d",&x,&i);
}
for (i=0;i<2;i++){
while (!isempty(s,i)){
pop(s,x,i);
printf ("%d ",x);
}
cout<<endl;
}
return 0;
}
顺序循环队列
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 8
#define OVERFLOW -2
using namespace std;
typedef int Elemtype;
typedef struct{
Elemtype data[MAXSIZE];
int rear,front;
}Seqqueue;
void initSeqqueue(Seqqueue &q){
q.rear=q.front=-1;
}
int emptySeqqueue(Seqqueue &q){
return q.rear==q.front;
}
int enSeqqueue(Seqqueue &q,Elemtype e){
//先判断是否队满
if ((q.rear+1)%MAXSIZE==q.front){
printf ("full!\n");
return 0;
}
q.rear=(q.rear+1)%MAXSIZE;
q.data[q.rear]=e;
return 1;
}
int deSeqqueue(Seqqueue &q,Elemtype &e){
if (emptySeqqueue(q)){
printf ("null!\n");
return 0;
}
q.front=(q.front+1)%MAXSIZE;
e=q.data[q.front];
return 1;
}
Elemtype getFront(Seqqueue &q){
if (emptySeqqueue(q)){
printf ("null!\n");
}
else {
Elemtype e;
q.front=(q.front+1)%MAXSIZE;
e=q.data[q.front];
return e;
}
}
void display(Seqqueue &q){
if (emptySeqqueue(q)){
printf ("null!\n");
}
else {
int i=(1+q.front)%MAXSIZE;
while (i<=q.rear){
printf ("%d ",q.data[i]);
i=(i+1)%MAXSIZE;
}
printf ("\n");
}
}
int getlength(Seqqueue &q){
return (q.rear-q.front+MAXSIZE)%MAXSIZE;
}
int main()
{
Seqqueue s;
initSeqqueue(s);
int x;
scanf ("%d",&x);
while (x!=-999){
enSeqqueue(s,x);
scanf ("%d",&x);
}
deSeqqueue(s,x);
printf ("%d ",x);
deSeqqueue(s,x);
printf ("%d ",x);
scanf ("%d",&x);
enSeqqueue(s,x);
deSeqqueue(s,x);
printf ("%d ",x);
cout<<endl;
return 0;
}
表达式求值
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
using namespace std;
typedef char Elemtype;
typedef struct {
Elemtype elem[MAXSIZE];
int top;
}SqStack;
void initSqstack(SqStack &s){
s.top=-1;
}
int isempty(SqStack &s){
return s.top==-1;
}
int push(SqStack &s,Elemtype e){
if (s.top>=MAXSIZE-1)
return 0;
else {
s.top++;
s.elem[s.top]=e;
return 1;
}
}
int pop(SqStack &s,Elemtype &e){
if (s.top==-1)
return 0;
else {
e=s.elem[s.top];
s.top--;
return 1;
}
}
Elemtype gettop(SqStack &s){
Elemtype e;
e=s.elem[s.top];
return e;
}
int in(Elemtype &c){
if (c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#'||c=='\n')
return 1;
else return 0;
}
char precede(Elemtype a,Elemtype b){
//比较两个运算符的优先级
if((a=='+'&&(b=='+'||b=='-'||b==')'||b=='#'))||(a=='-'&&(b=='+'||b=='-'||b==')'||b=='#'))
||(a=='*'&&(b=='+'||b=='-'||b=='*'||b=='/'||b==')'||b=='#'))||(a=='/'&&(b=='+'||b=='-'
||b=='*'||b=='/'||b==')'||b=='#'))||(a==')'&&(b=='+'||b=='-'
||b=='*'||b=='/'||b==')'||b=='#')))
return '>';
if ((a=='+'&&(b=='*'||b=='/'||b=='('))||(a=='-'&&(b=='*'||b=='/'||b=='('))
||(a=='*'&&b=='(')||(a=='/'&&b=='(')||(a=='('&&(b=='+'||b=='-'
||b=='*'||b=='/'||b=='('))||(a=='#'&&(b=='+'||b=='-'
||b=='*'||b=='/'||b=='(')))
return '<';
if((a=='('&&b==')')||(a=='#'&&b=='#'))
return '=';
}
Elemtype operate(Elemtype &a,Elemtype &th,Elemtype &b){
int aa=a-'0';
int bb=b-'0';
char c;
switch (th){
case '+':c=char(aa+bb+'0');
break;
case '-':c=char(bb-aa+'0');
break;
case '*':c=char(aa*bb+'0');
break;
case '/':c=char(aa/bb+'0');
break;
}
return c;
}
Elemtype evaluateExpression(){
SqStack optr,opnd;
initSqstack(optr);initSqstack(opnd);
push(optr,'#');
char c=getchar(),x,theta,a,b;
while (c!='#'||gettop(optr)!='#')
{
//输入#时表达式结束,操作符栈的栈顶元素为#时说明全部弹出并进行运算
//如果C是运算符则1, 比较栈顶元素的优先级大小,选择弹栈或者压栈
//如果C是数字,这里假定全部为十位数以内,则压栈。
//为什么这里是\\,我们想要设置为:两者都为#时循环结束,取非即为a!=#||b!#
if (!in(c))
{
push(opnd,c);c=getchar();
}else {
switch (precede(gettop(optr),c)){
case '>':
pop(optr,theta);
pop(opnd,a);
pop(opnd,b);
push(opnd,operate(a,theta,b));
//这里不用c=getchar()因为c此时仍然为优先级较小的运算符,应当将循环继续,与gettop的运算
//符相比,如果还是比top的运算符小,c还是不能进栈,直到满足<的条件时才能进栈。
break;
case '=':pop(optr,x);c=getchar();
break;
case '<':push(optr,c);c=getchar();
break;
}
}
}
return gettop(opnd);
}
int main()
{
Elemtype c=evaluateExpression();
cout<<c;
return 0;
}
这种做法的弊端是:只能运算十以内的数字,而且在运算过程中也不能产生大于等于十的结果。