1.栈的定义和特点
1.栈和队列是特殊的线性表。
2.栈是先进后出的线性表,
- 表示:typedef struct{Type *base;Type *top; int stacksize;}SqStack
- 其中base始终指向栈底,top随元素的添加一直指向栈顶。
- 可以有顺序实现和链表实现。
3.栈的应用举例:
- 数制转换
- 括号匹配
- 行编辑器帮助处理错误输入
- 迷宫求解
- 表达式求解 -
- 实现递归
2.队列的定义和特点
队列是先进先出的线性表。可以由链表实现和顺序实现。
3.思维导图
4.实验报告
(1) 编程实现顺序栈的基本操作,并应用栈的基本操作,实现:
c) 四则运算表达式(中缀或后缀)的求值。(选做)
(a)进制转换
com_def.h
#include <stdio.h>
#include <iostream>
#include <iomanip>
#include <string.h>
#include <malloc.h>
#include <process.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
typedef int Status;
stack_def.h
#define STACK_INIT_SIZE 100//存储空间的初始分配量
#define STACKINCREMENT 10//存储空间的分配增量
typedef int SElemType;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
stack_func.h
Status InitStack(SqStack &S){
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status StackEmpty(SqStack &S){
return(S.base==S.top);
}
int StackLength(SqStack S){
return(S.top-S.base);
}
Status GetTop(SqStack S,SElemType &e){
//若栈不空,则用e返回S的栈顶元素
if(S.top==S.base) return ERROR;
e=*(S.top-1);
return OK;
}
Status Push(SqStack &S,SElemType e){
//插入元素e为新的栈顶元素
if(S.top-S.base>=S.stacksize){
//若栈满,追加存储空间
SElemType *newbase=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!newbase) exit(OVERFLOW);
S.top=newbase+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;//*S.top=e;S.top++;
return OK;
}
Status Pop(SqStack &S,SElemType &e){
if(S.top==S.base) return ERROR;
e=*(--S.top);//--S.top;e=*S.top;
return OK;
}
//Status DestoryStack(SqStack &S){
//}
void Conversion_Integer(int N,int R){
//对于输入的任意一个非负十进制整数,打印输出与其等值的N进制数
int e=0;
SqStack S;
InitStack(S);
while(N){
Push(S,N%R);
N=N/R;
}
while(!StackEmpty(S)){
Pop(S,e);
if(e>=0&&e<=9)
printf("%d",e);
else
printf("%c",e-10+'A');
}
}
void Conversion_Decimal(float B,int R)
{
int e;
while(B>0.0001){
B=B*R;
e=(int)B;
B=B-e;
if(e>=0&&e<=9)
printf("%d",e);
else
printf("%c",e-10+'A');
}
}
#include "com_def.h"
#include "stack_def.h"
#include "stack_func.h"
using namespace std;
int main() {
float N=0;
int R=0;
cout<<"请输入需要转换的数值:"<<endl;
cin>>N;
cout<<"请输入需要转换成几进制:"<<endl;
cin>>R;
int A=0;//整数部分
float B=0;//小数部分
A=(int)N;
B=N-A;
//如果整数部分不为零,进行转换,否则输出0
if(A>0)
{
Conversion_Integer(A,R);//转换整数部分,并且输出
}
else
{
printf("0");
}
printf(".");//输出小数点
//如果小数部分部委为零,进行转换,否则输出0
if(B>0.00001){
Conversion_Decimal(B,R);//转换小数部分,并且输出
}
else
{
cout<<"0";
}
cout<<endl;
}
(b) 表达式的语法检查(括号的匹配)
com_def.h 同上
stack_def.h
#define STACK_INIT_SIZE 100//存储空间的初始分配量
#define STACKINCREMENT 10//存储空间的分配增量
typedef char SElemType;
typedef struct{
SElemType *base;//栈底指针
SElemType *top;//栈顶指针
int stacksize;
int length;
}SqStack;
stack_func.h
Status InitStack(SqStack &S){
S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}//初始化空栈
Status CreateStack(SqStack &S){
cout<<"请输入栈中元素个数:"<<endl;
int n = 0;
cin>>n;
S.length = n;
int i;
cout<<"请输入数据:"<<endl;
for(i = 0;i < S.length;i++){
cin>>S.base[i];
S.top++;
}
return OK;
}//建立栈
void OutputStack(SqStack S){
cout<<"栈为:";
for(int i = 0;i < S.length;i++){
cout<<S.base[i]<<" ";
}
cout<<endl;
}//输出栈
void DestoryStack(SqStack S){
free(S.base);
S.base = NULL;
S.top = NULL;
S.stacksize = 0;
}//销毁栈
Status StackEmpty(SqStack S){
if(S.base == S.top) return TRUE;
else return FALSE;
}//栈判空
Status GetTop(SqStack S,SElemType &e){
if(StackEmpty(S) == TRUE) return ERROR;
e = *(S.top-1);
return OK;
}//取栈顶元素
Status 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(OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize = S.stacksize + STACKINCREMENT;
}
*S.top++ = e;
S.length++;
return OK;
}//插入新栈顶元素
Status Pop(SqStack &S,SElemType &e){
if(StackEmpty(S) == TRUE) return ERROR;
e = * --S.top;
S.length--;
return OK;
}//删除栈顶元素
Status StackLength(SqStack S,SElemType &e){
e = S.length;
return OK;
}//求栈的长度
main.cpp
#include "com_def.h"
#include "stack_def.h"
#include "stack_func.h"
using namespace std;
int main() {
SqStack S;
SElemType e;
char ch[100];
char *p;
if(InitStack(S))
{
printf("请输入表达式\n");
gets(ch);
p = ch;
while (*p)
switch(*p){
case '(':
case '[':Push(S,*p++);
break;
case ')':
case ']':
if(!StackEmpty(S)){
Pop(S,e);
if(*p == ')' && e != '(' || *p == '[' && e != ']'){
printf("左右括号不配对");
exit(OVERFLOW);
}else{
p++;
break;
}
}else{
printf("缺乏左括号!\n");
exit(ERROR);
}
default : p++;
}
if(StackEmpty(S))
printf("左右括号匹配!\n");
else
printf("缺少右括号!\n");
}
return 0;
}
(2) 编程实现队列(链队列或循环队列)的基本操作,并应用栈和队列实现回文序列的判定。
com_def.h 如上
queue_def.h
typedef int QElemType;
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front;
QueuePtr rear;
}LinkQueue;//队列
queue_func.h
using namespace std;
Status InitQueue(LinkQueue &Q){
//建立空队列
Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
if(!Q.front) exit(OVERFLOW) ;//存储空间分配失败
Q.front->next = NULL;
return OK;
}
Status QueueEmpty(LinkQueue &Q){
//判断队列是否为空
if(Q.front==Q.rear){
return OK;
}else{
return FALSE;
}
}
Status CreateQueue(LinkQueue &Q){
int n;
cout<<"请输入队列元素个数:"<<endl;
cin>>n;
QueuePtr p;
p = (QueuePtr)malloc(sizeof(QNode));
if(!p) exit(OVERFLOW);
for(int i=0;i<n;i++){
scanf("%d",p->data);
p=p->next;
}
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}
Status EnQueue(LinkQueue &Q,QElemType e){
//插入队尾元素
QueuePtr p;
p = (QueuePtr)malloc(sizeof(QNode));
if(!p) exit(OVERFLOW);
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}
Status DeQueue(LinkQueue &Q,QElemType &e){
//删除队头元素
QueuePtr p;
if(QueueEmpty(Q)) return ERROR;
p = Q.front->next;
e = p->data;
Q.front->next = p->next;
if(Q.rear == p)
Q.rear = Q.front;
free(p);
return OK;
}
void OutputQueue(LinkQueue &Q){
//输出队列
QueuePtr p;
p = Q.front->next;
while(p!=NULL){
printf("%d ",p->data);
p = p->next;
}
}
Status DestroyQueue(LinkQueue Q){
//销毁队列
while(Q.front){
Q.rear = Q.front->next;
free(Q.front);
Q.front = Q.rear;
}
return OK;
}
main
#include "com_def.h"
#include "queue_def.h"
#include "queue_func.h"
using namespace std;
int main() {
LinkQueue Q;
QElemType e;
int option;
do{
cout<<"————————————"<<endl;
cout<<"* 请输入对队列的操作 *" <<endl;
cout<<"* 1:建立空队列 *"<<endl;
cout<<"* 2:插入队尾元素 *"<<endl;
cout<<"* 3:删除队头元素 *"<<endl;
cout<<"* 0:销毁队列并退出程序 *"<<endl;
cout<<"————————————"<<endl;
cin>>option;
switch(option){
case 1:
if(InitQueue(Q)==OK){
cout<<"初始化空队列成功!"<<endl;
}else{
cout<<"初始化失败!"<<endl;
}
break;
case 2:
cout<<"请输入想要插入的元素:"<<endl;
cin>>e;
if(EnQueue(Q,e)==OK){
cout<<"插入成功!"<<endl;
OutputQueue(Q);
cout<<endl;
}else{
cout<<"插入失败!"<<endl;
}
break;
case 3:
if(DeQueue(Q,e)==OK){
cout<<"删除成功!被删除的元素是:"<<endl;
cout<<e<<endl;
OutputQueue(Q);
cout<<endl;
}else{
cout<<"删除失败!"<<endl;
}
break;
}
}while(option);
DestroyQueue(Q);
return 0;
}