实验日期2010.4.26教师签字________________ 成绩__________【实验名称】第三章栈和队列的基本操作及应用【实验目的】(1)熟悉栈的特点(先进后出)及栈的基本操作,如入栈、出栈等,掌握栈的基本操作在栈的顺序存储结构和链式存储结构上的实现;(2)熟悉队列的特点(先进先出)及队列的基本操作,如入队、出队等,掌握队列的基本操作在队列的顺序存储结构和链式存储结构上的实现。
【实验内容】1.链栈的基本操作(链栈的初始化、进栈、出栈以及取栈顶的值)#include H stdio.h H#include H malloc.h ninclude "stdlib.h"typedef int Elemtype;typedef struct stacknode {Elemtype data;stacknode * next;JStackNode;typedef struct {stacknode * top; 〃栈顶指针} LinkStack;/*初始化链栈*/void InitStack(LinkStack * s){ s->top=NULL;printf("\n已经初始化链栈!\n”);)/*链栈置空*/void setEnipty(LinkStack * s){ s・>top 二NULL;printf(H\n 链栈被置空! \n”);}/*入栈*/void pushLstack(LinkStack * s, Elemtype x){ StackNode * p; p=(StackNode *)maHoc(sizeof(StackNode)); 〃建立一个节点° p->data=x;p->next=s->top; //ill于是在栈顶pushLstack,所以要指向栈顶。
s->top=p; 〃插入}/*出栈勺Elemtype popLstack(LinkStack * s){ Elemtype x;StackNode * p; p=s->top; 〃指向栈顶if (s->top ==0){ printf("\n栈空,不能出栈!\n”); exit(-l);}x=p->data;s->top=p->next; 〃当前的栈顶指向原栈的nextfree(p); 〃释放return x;}/*取栈顶元素*/Elemtype StackTop(LinkStack *s){ if (s->top ==0){ printf(H\n 链栈空\n”);exit(-l);)return s->top->data;}/*遍历链栈*/void Disp(LinkStack * s){ printf("\n链栈中的数据为:\n");printf(H======================================\n n); StackNode * p;p=s->top;while (p!=NULL){ printf(H%d\n'\p->data);p=p->next;} printf("=======================================\n");}void main(){ printf(H====================链栈操作==========\n\nj;int i,m,n,a; LinkStack * s; s=(LinkStack *)malloc(sizeof(LinkStack)); int cord;do{ printf(H\n n);printf(”第一次使用必须初始化! \n H);printf(H\ii 主菜单W);printf(H\n 1 初始化链栈\n“);printf(H\n 2 入栈\n“);printf(M\ii 3 出栈\n");printf(H\n 4 取栈顶元素\n");printf(H\n 5 置空链栈\n");printf(H\n 6 结束程序运行\n”);printf(H\n ---------------------------------printfC*请输入您的选择(1,2, 3, 4, 5,6)”);scanf(M%d,\&cord);printf(H\n n);switch(cord){ case 1:{ InitStack(s);Disp(s);} break;case 2:(printfC输入将要压入链栈的数据的个数:I匸“);scanf(”%d”,&n);printf(”依次将%d个数据圧入链栈:\n",n);for(i=l;i<=n;i++){scanf("%d”,&a); pushLstack(s,a);}Disp ⑸;[break;case 3:{ printf("\n出栈操作开始!\n“); printf("输入将要出栈的数据个数:m=”);scrmf(”%d:&m);for(i=I;i<=m;i++){printf("\n 第%d 次出栈的数据是:%d",i,popLstack(s));)Disp(s);[break;case 4:{ printf("\n\n 链栈的栈顶元素为:%d\n",StackTop(s)); printf(H\n H);(break;case 5:{ setEnipty(s);Disp(s);(break;case 6:exit(O);})while (cord<=6);}2.顺序栈的基本操作(顺序栈的初始化、进栈、出栈以及取栈顶的值) #include<stdio.h>#include<malloc.h>#include<stdlib.h>#define STACKSIZE 100#define STACKINCREMENT 10#define null 0typedef struct {int 水base;int *top;int stacksize;}SqStack;SqStack Initstack(){SqStack S;S.base=(int *)malloc(STACKSIZE*sizeof(int));if(!S.base){printf("\n 存储分配失败\n");exit(0);}S.top=S.base;S.stacksize 二STACKSIZE;return S;}int StackEmpty(SqStack S){if(S.top==S.base) return 1;else return 0;}int StackLength(SqStack S){int *p;p=S.base;for(int i=0;p!=S・top;p++,i++);return i;int GetTop(SqStack S)int e;if(StackEmpty(S)) {printf(”当前栈为空,不能执行此操作\n”);exit(O);}e=*(S.top-l);return e;}int Push(SqStack &Sjnt e){if(StackLength(S)>=S.stacksize) {S.base=(int*)realloc(S.base,(STACKSIZE+STACKINCREMENT)*sizeof(int));if(!S.base){printf("\n 再分配存储失败\n");return 0;}S ・ top=S ・ base+S. stacksize;S.stacksize+二STACKINCREMENT;}*S.top++=e;return 1;}int Pop(SqStack &S){int e;if(StackEmpty(S)){printf("当前栈为空,不能执行此操作\n”);exit(0);}e=*—S.top;return e;}void main(){int i=0,e;int *p;SqStack S;S=Initstack();printf("\n 1.元素进栈\n 2.元素出栈\n 3.取栈顶元素\n 4. 求栈的长度\n 5.判栈空\n 6.退出\n“);for(;i!=6;){printf(“\n请选择你要进行的操作:“);scanf(H%d\&i);switch(i){case l:printf("\n请输入进栈元素:");scanf(”%cT,&e);Push(S,e);p=S.base;printf("\n当前栈中元素:"); if(StackEmpty(S))printfC'当前栈为空\n”); while(p!=S.top){printf(n%d '\*p);p++;}break;case 2:printf("\n%d 已出栈\n",Pop(S)); printf("\n当前栈中元素:”);if(StackEmpty(S))printf(,'当前栈为空\n“);p=S.base;while(p !=S .top) {printf(" %d ",*p);p++;} break;case 3:printf("\n 栈顶元素为:%d\n",GetTop(S));break;case 4:printf("\n 栈的长度为:%d\n",StackLength(S));break;case 5:if(StackEmpty(S))printf("\n 当前栈为空\n");else printf("\n 当前栈不空\n"); break;default:printf("\n 退出程序\n");}}}3•顺序队列的基本操作(顺序队的初始化、进队、出对以及取对头)#include <stdio.h>#include <malloc.h>#define MAXNUM 100#define Elemtype int#define TRUE 1#define FALSE 0typedef struct{ Elemtype queuefMAXNUM];int front;int rear;Jsqqueue;/*队列初始化*/int initQueue(sqqueue *q){ if(!q) return FALSE;q->front=-1;q->rear=-1;return TRUE;}/*入队*/int append(sqqueue Elemtype x){ if(q->rear>=MAXNUM-1) return FALSE;q->rear++;q->queue[q->rear]=x;return TRUE;/*出队*/Elemtype Delete(sqqueue *q){ Elemtype x;if (q->front==q->rear) return 0;x=q->queue[++q->front];return x;}/*判断队列是否为空*/int Empty(sqqueue *q){ if (q->front=q->rear) return TRUE;return FALSE;}/*取队头元素*/int gethead(sqqueue *q){ if (q->front==q->rear) return 0; return(q->queue[q->front+1]);)/*遍历队列*/void display(sqqueue *q){ int s;s=q->front;if (q->front==q->rear) printf(”队列空!\n“);else{printf("\n顺序队列依次为:“);while(s<q->rear){s=s+l;printf(H%d<-'\ q->queue[s]);}printf(H\n H);printf("顺序队列的队尾元素所在位置:rear=%d\n",q->rear); printf("顺序队列的队头元素所在位S: front=%d\n " ,q->front);})/*建立顺序队列*/void Setsqqueue(sqqueue *q){ int njjn;printf("\n请输入将要入顺序队列的长度:”);scanf(H%d,r,&n);printfC*\n请依次输入入顺序队列的元素值:\n“);for (i=0;i<n;i++){ scanf(”%d”,&m);append(qjn);}main(){ sqqueue *head;int x,y,z,select; head=(sqqueue*)malloc(sizeof(sqqueue));do{printf("\n第一次使用请初始化!\n");printf("\n 请选择操作(1 -7):\n”);pri ntf("=================================\n"); printf(n l 初始化\n“);printf("2建立顺序队列\n");printf("3 入队\n”);printf("4 出队\n“);printf("5判断队列是否为空\n“);printf("6取队头元素\n");printf(H7 遍历队列\n“);printf(,,===================================\n");scanf("%d",&select);switch(select){case 1:{ initQueue(head);printfC'B经初始化顺序队列! \n“); break;)case 2:{ Setsqqueue(head);printf("\n已经建立队列!\n");display(head); break;)case 3:{ printf("请输入队的值:\n”);scanf(”%cT,&x);append(head,x); display(head);break;)case 4:{ z=Delete(head);printf("\n队头元素%(1已经出队!\n",z); display(head);break;)case 5:if(Empty(head))printf(”队列空\n”);elseprintf("队列非空\n“);break;}case 6:{ y=gethead (head);printf("队头元素为:%d\n",y);break;)case 7:{ display(head);break;}}}while(select<=7);}4•链队列的基本操作(链队列的初始化、进队、出对操作)#include<stdio.h>#include<stdlib.h>#define ElemType inttypedef struct Qnode{ ElemType data;struct Qnode *next;(Qnodetype;typedef struct{ Qnodetype *front;Qnodetype *rear;JLqueue;/*初始化并建立链队列*/void creat(Lqueue *q){ Qnodetype *h;int i,n,x;printf(”输入将建立链队列元素的个数:n=”);scanf(“%d",&n);h=(Qnodetype*)malloc(sizeof(Qnodetype));h->next=NULL;q->front=h;q->rear=h;for(i=l;i<=n;i++){ printfC链队列第%<1个元素的值为:”,i);scanf(“%d”,&x);Lappend(q,x);)/*入链队列*/void Lappend(Lqueue *q,int x){ Qnodetype *s; s=(Qnodetype*)manoc(sizeof(Qnodetype)); s->data=x;s->next=NULL;q->rear->next=s;q->rear=s;}/*出链队列勺ElemType Ldelete(Lqueue *q){ Qnodetype *p;ElemType x;if(q->front==q->rear){ printfC* 队列为空!\n“);x=0;)else{ p=q->front->next;q->front->next=p->next; if(p->next=NULL) q->reai*=q->front;x=p->data;free(p);}return(x);)/*遍历链队列*/void display(Lqueue *q){ Qnodetype *p;p=q->front->next; /*指向第一个数据元素节点*/printf("\n链队列元素依次为:”);while(p!=NULL){ printf("%d—>",p->data);p=p->next;}printf(H\n\n遍历链队列结束!\n n);}main(){ Lqueue *p;int x^cord;printf(H\n*****第一次操作请选择初始化并建立链队列! **林*\口”);W); switch(cord){ case 1:{ p=(Lqueue *)malloc(sizeof(Lqueue)); creat(p);display(p);} break;case 2:{ printf (“请输入队列元素的值:x=“);scanf(”%d”,&x);Lappend(p,x); display(p);(break;case 3:{ printf(n 出链队列元素:x=%d\ii*\Ldelete(p));display(p);(break;case 4:{display(p);) break;case 5:{exit (0);) }(while (cord<=5);) 5 •循环队列的基本操作:#include<stdio.h> #include<iostream.h> #include<malloc.h> #define maxsize 100 struct Queueint *base; int front; int rear;);void initQueue(Queue &Q){Q.base=(int *)malloc(maxsize*sizeof(int));Q.front=Q.rear=0; printf(M 1初始化并建立链队列 \n n ); printf (” 2入链队列 S'); printf (” 3 出链队列 S');printf(H 4 遍历链队列W); printf(H 5 结束程序运行W); 主菜单 W); printf(H =======================================\n H );printf(Hscanf(M %d 1',&cord);do { printf(H \n链队列的基本操作\n J ; printf(H = printf(n W);}int QueueLen(Queue Q){return(Q.rear- Q・ front+maxsize)%maxsize;}void EnQueue(Queue &Q,int e){if((Q.rear+1 )%maxsize=Q.front)cout«"队列已满,无法插入!"«endl;else{Q.base[Q.rear]=e; Q.reai-(Q.rear+ l)%maxsize;)}int DeQueue(Queue &Q,int &e){if(Q.reai"==Q.front) coutvv"队列已空,无法删除「vvendl; else{e=Q.base[Q.front]; Q.front=(Q.front+1 )%maxsize;cout«"被删除的元素是:,,<<'\t'«e«endl;return e;})void main(){Queue Q;initQueue(Q);loop:cout«、Fvv"请选择你要进行的操作:"«endl;cout«'\t'«" 1 .插入元素"<<endl«'\t'«,'2.删除元素"<<endl«,\t'«"3.求队列长度,,<<endl«,\t,«,,4.结束u«endl;int i; cin»i;switch(i){case(l):{int e;coutvv”请输入要插入的元素: cin»e;EnQueue(Q,e);goto loop;}case(2):{int e;DeQueue(Q.e);goto loop;}case(3):{int 1;l=QueueLen(Q);cout«"队列的长度为:"«'\t'«l«endl; goto loop;)case(4): break;default:cout«"输入错误,请重新输入!"«endl;goto loop;}}6 •两个栈实现队列的功能#include<stdio.h>#include<malloc.h>#include<stdlib.h>#include<iostream.h>#define STACK_INIT_SIZE 100#define STACKINCREMENT 10typedef char SElemType;typedef struct{SEIeniType *base;SEleniType *top;int stacksize;JSqStack;〃队列III两个栈S1.S2构成typedef struct{SqStack S1;SqStack S2;}Queue;void InitStack(SqStack *S)S->base=(SElemType *)malloc(STACKJNIT_SIZE*sizeof(SElemType)); if(!S->base) exit(O);S->top=S->base; S->stacksize=STACK_INIT_SIZE;}void push(SqStack *S,SElemType e){if(S->top-S->base==S->stacksize){S・> base=(SElemType*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(SElemType));if(!S->base) exit(O);S->top=S->base+S->stacksize;S->stacksize+=STACKINCREMENT;}*(S->top)++=e;}void pop(SqStack *S,SElemType *e){if(S->top==S->base) exit(O);S->top—; *e=*(S->top);}〃队列的相关操作void InitQueue(Queue *Q){InitStack(&(Q->S 1 ));InitStack(&(Q->S2));}void EnQueue(Queue *Q,SElemType e){push(&(Q->S l),e);)void DeQueue(Queue *Q,SElemType *e){if((Q->S2). top==(Q->S2). base){while((Q->S 1 ).top!=(Q->S 1 ).base) {pop(&(Q->S 1 ),e);push(&(Q->S2),*e);} pop(&(Q->S2),e);}else pop(&(Q->S2),e);}int QueueEmpty(Queue Q)if(Q.S 1 .base==Q.S 1 .top&&Q・S2・bjse==Q・S2・top) return 0; else return 1; void main(){SEIemType e; Queue Q; int i;InitQueue(&Q);for(i=0;i< 10:i++) EnQueue(&Q/a,+i); while(QueueEmpty(Q)!=O){DeQueue(&Q,&e); cout«e;}cout«endl;}7・用双端队列模拟栈#include<stdio.h>#include<malloc.h>#include<stdlib.h>#define null 0typedef struct QNode{int data;struct QNode *next;struct QNode *prior;)QNode;typedef struct)QNode *frontL*front2;QNode *rearl,*rear2;}LinkDeque;LinkDeque InitQueue(){LinkDeque Q;Q.front 1 =Q.rearl =(QNode *)malloc(sizeof(QNode)); if(!Q.front 1){printf("\n 存储分配失败\n");exit(O);} Q.front2=Q.rear2=(QNode *)malloc⑸zeof(QNode));if(!Q.front2){printf("\n 存储分配失败\n H);exit(O);) Q. front l->next=Q.front2;Q.front2->next=Q.frontl;return Q;}int EnDeque(LinkDeque &Q,int e){QNode *p;p=(QNode *)malloc(sizeof(QNode)); if(!p){printf("\n 存储分配失败\n");exit(O);} p->data=e;p->next=Q.front2;p->prior=Q.rearl;Q.rearl->next=p;Q.reail 二p;Q.rear2=Q.front 1 ->next;return 1;}int DeDeque(LinkDeque &Q){int e;QNode *p;if(Q.front 1 ==Q.rear 1){printf("栈为空,不能执行删除操作\n");return 0;)p=Q.rearl;e=p->data;p->prior->next=p->next;p->next->prior=p->prior;Q.rearl=p->prior;if(Q.front l==Q.front2){Q.rear 1=Q.front l;Q.rear2=Q.front2;} free(p);return e;}int DequeLength(LinkDeque Q){int len=0;QNode *p;p=Q.frontl->next;while(p!=Q.front2){ Ien++;p=p->next;)return len;}int Gethead(LinkDeque Q){QNode *p;if(Q.front 1 !=Q.rear 1){p=Q.rear 1 ;return p->data;}}void main(){int i=0,e;LinkDeque Q;QNode *p;Q=InitQueue();printf(n\n 1.元素进栈\n 2.元素出栈\n 3.求栈的长度\n 4. 取栈顶元素\n 5.退出\n");for(:i!=5;){printf(-\n请选择你要进行的操作:”);scanf(n%d\&i);switch(i){case l:printf("\n请输入进栈元素:”);scanf(”%cT,&e);EnDeque(Q,e);if(Q.front 1 !=Q.rearl){printf("\n 当前栈元素:");p=Q.front 1 ->next;while(p!=Q.front2){ printf(H%d '\p->data);p=p->next;}}else printf(n当前栈为空\iT);break;case 2:if(Q.frontl!=Q.rearl)printf(H\n 已删除%d\n*\DeDeque(Q));eIse printfC*栈为空,不能此删除操作\n“);if(Q.frontl !=Q.rearl)(printf("\n 当前栈元素:");p=Q.frontl・>next;while(p!=Q.front2){ printf(H%d H,p->data);p=p->next;}}else printfC当前栈为空E);break;case 3:printf(M\n 栈的长度:%d,\DequeLength(Q));break;case 4:if(Q.front 1 !=Q.rearl)printf(H\n 栈顶元素:%d\n”,Gethead(Q));else printfC栈为空,不能此删除操作\n H);break;default:printf("\n 结束程序\n");}1}&约瑟夫队列:#include<stdio.h>#include<malloc.h>#include<iostream.h>#define len sizeof(struct QNode)struct QNode{int data;QNode *next;};void main(){int m,n,k,i,e,num=l;cout«"请输入总人数:"«endl; cin»n;cout«"请输入出局数:"«endl; cin»m;coutvv"请输入开始报数人的编号:"«endl; cin»k;QNodeQ=(QNode *)malloc(len);Q->next=Q;Q->data= 1; p二Q;for(i=2;i<=n;i++){p->next=(QNode *)malloc(len);p=p->next;p->data=i;)p->next=Q;r=Q;t=r;for(i= 1 ;i<=k-1 ;i++){ t=r;r=r->next;}cout«"出队顺序为:"vvendl;do{for(i= 1 ;i<=m-1 ;i++){ t=r;r=r->next;)e=r->data;t->next=r->next;r=t->next;cout«e«H H; num++;}while(num<=n);cout«endl;)【小结讨论】1.一个程序中如果要用到两个栈时,可通过两个栈共享一维数组来实现,即双向栈共享邻接空间。