【数据结构】第三章 栈和队列

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;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值