栈和队列
一、实习目的
1. 掌握栈这种数据结构特性及其主要存储结构,并能在现实生活中灵活运用。
2. 掌握队列这种数据结构特性及其主要存储结构,并能在现实生活中灵活运用。
3. 了解和掌握递归程序设计的基本原理和方法。
二、实例
在各种教科书中关于栈和队列叙述十分清晰。但是,它们在计算机内的实现介绍不够详细。为了减轻学生上机实验的困难,在此给出几个例题供参考。
1. 栈的顺序存储结构及实现。
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20 /* 数组最大界限 */
typedef int ElemType; /* 数据元素类型 */
typedef struct
{ ElemType a[MAXSIZE]; /* 一维数组子域 */
int top; /* 栈顶指针子域 */
}SqStack; /* 栈的顺序结构体类型 */
SqStack s1;
/* 函数声明 */
void init_s(SqStack *s);
void out_s(SqStack s);
void push(SqStack *s,ElemType e);
ElemType pop(SqStack *s);
/* 主函数 */
main()
{ int k; ElemType e,x; char ch;
init_s( &s1); /* 初始化一个空栈 */
do { printf("\n\n\n");
printf("\n\n 1. 数据元素e进栈 ");
printf("\n\n 2. 出栈一个元素,返回其值");
printf("\n\n 3. 结束程序运行");
printf("\n======================================");
printf("\n 请输入您的选择 (1,2,3)");
scanf("%d",&k);
switch(k)
{ case 1:{ printf("\n 进栈 e=?"); scanf("%d",&e);
push( &s1,e); out_s( s1 );
} break;
case 2:{ x= pop( &s1);
printf("\n出栈元素 : %d", x);
out_s( s1 );
} break;
case 3: exit(0);
} /* switch */
printf("\n ----------------");
}while(k>=1 && k<3);
printf("\n 再见!")
printf(“\n 打回车键,返回。“); ch=getch();
} /* main */
/* 初始化空栈 * /
void init_s(SqStack *s)
{ s->top=-1;
} /* init_s */
/* 输出栈的内容 */
void out_s(SqStack s)
{ char ch; int i; /* 千万不能修改栈顶指针top */
if (s->top==-1) printf(“\n Stack is NULL. “);
else{ i=s->top;
while( i!=-1){ printf(“\n data=%d”, s->a[i]);
i--; }
}
printf(“\n 打回车键,继续。“); ch=getch();
} /* out_c */
/* 进栈函数 */
void push(SqStack *s,ElemType e)
{ if(s->top==MAXSIZE-1)printf(“\n Sstack is Overflow!”);
else{ s->top++ ;
s->a[s->top]=e;
}
}/* push */
/* 出栈函数 */
ElemType pop(SqStack *s)
{ ElemType x;
if(s->top==-1){ printf(“\n Stack is Underflow!”);
x=-1; }
else { x=s->a[s->top];
s->top--; }
return(x);
} /* pop */
2. 循环队列(即队列的顺序存储结构)实现。
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20 /* 数组最大界限 */
typedef int ElemType; /* 数据元素类型 */
typedef struct
{ ElemType a[MAXSIZE]; /* 一维数组子域 */
int front,rear; /* 头、尾指针子域 */
}SqQueue; /* 循环队列的结构体类型 */
SqQueue Q1;
/* 函数声明 */
void init_Q(SqQueue *Q);
void out_Q(SqQueue Q);
void EnQueue(SqQueue *Q,ElemType e);
ElemType DeQueue(SqQueue *Q);
/* 主函数 */
main()
{ int k; ElemType e,x; char ch;
init_Q( &Q1); /* 初始化一个空循环队列 */
do { printf("\n\n\n");
printf("\n\n 1. 数据元素e进队列 ");
printf("\n\n 2. 出队一个元素,返回其值");
printf("\n\n 3. 结束程序运行");
printf("\n======================================");
printf("\n 请输入您的选择 (1,2,3)");
scanf("%d",&k);
switch(k)
{ case 1:{ printf("\n 进队 e=?"); scanf("%d",&e);
EnQueue(SqQueue &Q1,e); out_Q(Q1);
} break;
case 2:{ x= DeQueue(&Q1);
printf("\n出队元素 : %d", x);
out_Q(Q1 );
} break;
case 3: exit(0);
} /* switch */
printf("\n ----------------");
}while(k>=1 && k<3);
printf("\n 再见!");
printf(“\n 打回车键,返回。“); ch=getch();
} /* main */
Q1.front |
3 |
4 |
5 |
0 |
1 |
2 |
Q1.rearr |
空循环队列 |
void init_Q(SqQueue *Q)
{ Q->front=0; Q->rear=0;
} /* init_Q */
/* 输出队列的内容 */
void out_Q(SqQueue Q)
{ char ch; int i;
/* 不能修改队列头、尾指针 */
if (Q->front==Q->rear) printf(“\n Queue is NULL. “);
else{ i=(Q->front+1)% MAXSIZE;
while( i!=Q->rear){ printf(“\n data=%d”, Q->a[i]);
i=(i+1)%MAXSIZE; }
printf(“\n data=%d”, Q->a[i]);
}
printf(“\n 打回车键,继续。“); ch=getch();
} /* out_Q */
/ * 进队函数 */
void EnQueue(SqQueue *Q,ElemType e)
{ if((Q->rear+1)%MAXSIZE==Q->front) printf(“\n Queue is Overflow!”);
else{ Q->rear=(Q->rear+1)% MAXSIZE ;
Q->a[Q->rear]=e;
}
}/* EnQueue */
Q1.front |
3 |
4 |
5 |
0 |
1 |
2 |
Q1.rear |
11 |
12 |
进队两个数据后 |
/* 出队函数 */
ElemType DeQueue(SqQueue *Q)
{ ElemType x;
if(Q->front==Q->rear)
{ printf(“\n Queue is NULL!”);
x=-1;
}
else { Q->front=(Q->front+1)% MAXSIZE ;
x=Q->a[Q->front];
}
return(x);
} /* DeQueue */
3. 队列的链表储结构及实现。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef int ElemType;
typedef struct QNode
{ ElemType data; /* 数据子域 */
struct QNode *next; /* 指针子域 */
}QNode; /* 结点结构类型 */
typedef struct
{ Qnode *front, *rear; /* 头、尾指针子域 */
}L_Queue; /* “头尾”结点结构类型 */
L_Queue Q1;
/* 函数声明 */
void init_Q(L_Queue *Q);
void out_Q(L_Queue Q);
void EnQueue(L_Queue Q,ElemType e);
ElemType DeQueue(L_Queue Q);
/* 主函数 */
main()
{ int k; ElemType e,x; char ch;
init_Q( &Q1); /* 初始化一个空循环队列 */
do { printf("\n\n\n");
printf("\n\n 1. 数据元素e进队列 ");
printf("\n\n 2. 出队一个元素,返回其值");
printf("\n\n 3. 结束程序运行");
printf("\n======================================");
printf("\n 请输入您的选择 (1,2,3)");
scanf("%d",&k);
switch(k)
{ case 1:{ printf("\n 进队 e=?"); scanf("%d",&e);
EnQueue(SqQueue &Q1,e); out_Q(Q1);
} break;
case 2:{ x= DeQueue(&Q1);
printf("\n出队元素 : %d", x);
out_Q(Q1 );
} break;
case 3: exit(0);
} /* switch */
printf("\n ----------------");
}while(k>=1 && k<3);
printf("\n 再见!");
printf(“\n 打回车键,返回。“); ch=getch();
} /* main */
/* 初始化一个空队列 */
∧ |
Q.front |
Q.rear |
空链表队列 |
{ QNode *p ;
p=(QNode *)malloc(sizeof(QNode));
p->next=NULL;
Q->fornt=p; Q->rear=p;
} /* init_Q */
/* 输出队列的内容 */
void out_Q(L_Queue Q)
{ QNode *p; char ch;
p=Q.front->next;
while(p!=NULL) { printf(“\n %d”,p->data);
p=p->next;
}
printf(“\n 打回车键,继续。“); ch=getch();
} /* out_Q */
/ * 进队函数 */
void EnQueue(L_Queue Q,ElemType e)
{ QNode p,s;
s=(QNode *)malloc(sizeof(QNode));
s->data=e; s->next=NULL;
Q.rear->next=s; Q.rear=s;
} /* EnQueue */
有一个数据元素的链表队列 |
Q.front |
Q.rear |
∧ |
11 |
/* 出队函数 */
ElemType DeQueue(L_Queue Q)
{ ElemType x; QNode *p;
if(Q.front==Q.rear) { printf(“\n Queue is NULL!”);
x=-1;
}
else { p=Q.front->next;
x=p->data;
Q.front->next=p->next;
If(Q.rear= =p) Q.rear=Q.fornt;
Free(p);
}
return(x);
} /* DeQueue */