- 若希望循环队列中的元素都得到利用,则需要设置一个标志域tag,并且以tag的值为0或1来区分队头指针front和队尾指针rear相同的队列状态是“空”还是“满”
#ifndef T1_H
#define T1_H
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#define MaxSize 10//定义栈中元素的最大个数
typedef int ElemType;
typedef struct{
ElemType data[MaxSize];
int front,rear;//front指向队头元素,rear指向队尾的下一个位置(也就是下一个应该插入的位置
int tag;//0表示出队操作,1表示入队操作,只有在指针相同且是出队操作才表示空,在指针相同的入队操作表示满
}SqQueue;
void InitSqQueue(SqQueue *Q);//初始化
bool EnSqQueue(SqQueue *Q,ElemType x);//入队操作
bool DeSqQueue(SqQueue *Q,ElemType *x);//出队操作
#endif
#include "t1.h"
void InitSqQueue(SqQueue *Q){
(*Q).rear=(*Q).front=0;
(*Q).tag=0;
}
bool EnSqQueue(SqQueue *Q,ElemType x){
if((*Q).rear==(*Q).front&&(*Q).tag==1)//队列满
return false;
(*Q).data[(*Q).rear]=x;
(*Q).rear=((*Q).rear+1)%MaxSize;
(*Q).tag=1;
return true;
}
bool DeSqQueue(SqQueue *Q,ElemType *x){
if((*Q).rear==(*Q).front&&(*Q).tag==0)//队空
return false;
(*Q).tag=0;
*x=(*Q).data[(*Q).front];
(*Q).front=((*Q).front+1)%MaxSize;
return true;
}
void printfSqQueue(SqQueue Q){
if(Q.rear==Q.front&&Q.tag==0)
return;
do{
printf("%d<-",Q.data[Q.front]);
Q.tag=0;
Q.front=(Q.front+1)%MaxSize;
}while(Q.rear!=Q.front&&Q.tag==0);
printf("\n");
}
void test1(){
SqQueue Q;
InitSqQueue(&Q);
ElemType x=0;
scanf("%d",&x);
while(x!=999){
EnSqQueue(&Q,x);
scanf("%d",&x);
}
// printf("%d-%d\n",Q.front,Q.rear);
printfSqQueue(Q);
DeSqQueue(&Q,&x);
printfSqQueue(Q);
}
void main(){
test1();
}
- 假设一个算数表达式中包括圆括号,方括号和花括号三种类型的括号,编写一个算法来判别表达式中的括号是都匹配,以字符"\0"作为算数表达式的结束符
思路:遇到左括号入栈
遇到有括号,出栈匹配,同一类型括号且左右括号匹配成功,其他失败
全部匹配成功且栈为空,匹配成功
#ifndef LISTACK_H
#define LISTACK_H
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
// 链栈,不带头结点的情况
typedef char ElemType;
typedef struct LinkNode{
ElemType data;//数据域
struct LinkNode *next;//这里的定义是有问题的,在栈中应该设计一个top指针,但是考虑到手比脑快代码都写完了就不改了,介意的话把next改名为top就可以了
}LinkNode,*LinkStack;
bool InitStack4(LinkStack *s);//初始化不带头结点的栈
bool Push4(LinkStack *s,ElemType x);//入栈
bool Pop4(LinkStack *s,ElemType *x);//出栈
void printfStack4(LinkStack s);//打印
bool EmptyStack4(LinkStack s);//空栈
#endif
#include "listack.h"
bool InitStack4(LinkStack *s){
*s=NULL;//栈空,不带头结点
return true;
}
bool EmptyStack4(LinkStack s){
if(s==NULL){
return true;
}
return false;
}
bool Push4(LinkStack *s,ElemType x){
LinkNode *p=(LinkNode *)malloc(sizeof(LinkNode));
if(p==NULL)
return false;
p->data=x;
// 这一步很容易错
p->next=(*s);
(*s)=p;
return true;
}
bool Pop4(LinkStack *s,ElemType *x){
if((*s)==NULL)//空表
return false;
LinkNode *p=*s;
*s=(*s)->next;
*x=p->data;
free(p);
return true;
}
void printfStack4(LinkStack s){
// s=NULL;
LinkNode *p=s;
while(p!=NULL){
printf("%c->",p->data);
p=p->next;
}
printf("\n");
}
// void test4(){
// LinkStack s;
// InitStack4(&s);
// // printfStack4(s);
// Push4(&s,1);
// Push4(&s,2);
// printfStack4(s);
// ElemType x=0;
// Pop4(&s,&x);
// printfStack4(s);
// }
// void main(){
// test4();
// }
#include "listack.h"
// 假设字符串中只有三种括号 {} [] ()
bool ifMatch(char c[],int len){
if(len==0)
return true;
LinkStack s;
InitStack4(&s);
for(int i=0;i<len;i++){
if(c[i]=='{'||c[i]=='('||c[i]=='['){//左括号入栈
Push4(&s,c[i]);
}else if(c[i]=='}'||c[i]==')'||c[i]==']'){
if(EmptyStack4(s))//如果是右括号需要被匹配但是栈空,直接返回false
return false;
char temp=' ';
Pop4(&s,&temp);
if(c[i]=='}'&&temp!='{')
return false;
else if(c[i]==']'&&temp!='[')
return false;
else if(c[i]==')'&&temp!='(')
return false;
}
}
if(!EmptyStack4(s))//所有都正常匹配,但是左括号还有多余的
return false;
return true;
}
- 车厢调度,两个铁道之间都是单向行驶道,火车调度站有一个用于调度的“栈道”,火车调度站的入口有n节硬座和软座车厢,(分别用H和S表示)等待调度,编写算法,输出对这n节车厢进行调度的操作序列,使得所有软座车厢都被调整到硬车厢之前。
体会数组和指针之间的联系
#include "t2.h"
// 函数声明
bool InitStack4(LinkStack *s);//初始化不带头结点的栈
bool Push4(LinkStack *s,ElemType x);//入栈
bool Pop4(LinkStack *s,ElemType *x);//出栈
void printfStack4(LinkStack s);//打印
bool EmptyStack4(LinkStack s);//空栈
void train(char *train){
char *p=train,*q=train,c=' ';
LinkStack s;
InitStack4(&s);
while(*p){
if(*p=='H')
Push4(&s,*p);
else
*(q++)=*p;
p++;
}
while(!EmptyStack4(s)){
Pop4(&s,&c);
*(q++)=c;
}
}
void test2(){
char c[]="HHHHSSSSSHSHSHSH";
train(c);
int index=0;
while(c[index]!='\0'){
printf("%c",c[index++]);
}
}
void main(){
test2();
}
bool InitStack4(LinkStack *s){
*s=NULL;//栈空,不带头结点
return true;
}
bool EmptyStack4(LinkStack s){
if(s==NULL){
return true;
}
return false;
}
bool Push4(LinkStack *s,ElemType x){
LinkNode *p=(LinkNode *)malloc(sizeof(LinkNode));
if(p==NULL)
return false;
p->data=x;
// 这一步很容易错
p->next=(*s);
(*s)=p;
return true;
}
bool Pop4(LinkStack *s,ElemType *x){
if((*s)==NULL)//空表
return false;
LinkNode *p=*s;
*s=(*s)->next;
*x=p->data;
free(p);
return true;
}
void printfStack4(LinkStack s){
// s=NULL;
LinkNode *p=s;
while(p!=NULL){
printf("%c->",p->data);
p=p->next;
}
printf("\n");
}
// void test4(){
// LinkStack s;
// InitStack4(&s);
// // printfStack4(s);
// Push4(&s,'1');
// Push4(&s,'2');
// printfStack4(s);
// ElemType x=0;
// Pop4(&s,&x);
// printfStack4(s);
// }
// void main(){
// test4();
// }
- 某汽车轮渡口,过江渡船每次能载10辆车过江,过江车辆分为客车类和货车类,上渡船有如下规定:同类车先上船,客车先于货车上船,且每上4辆客车才允许上一辆货车,若等待的客车不足4辆,则以或车代替,若无货车等待,允许客车都上船。使设计算法模拟以上渡口管理。
思路:这里设计一种最大长度为10的队列,用Q存储要过车的顺序,QH表示货车的队列,QK表示客车队列,每次对过车的车辆先分类,对于客车,每4辆客车加一辆货车,然后对应balance标志位置0,客车空或者货车空就可把剩下的另一种类型车全部入Q队列,这里值得注意的是,因为设计的队列长度为10,所以对于大于10的车辆不会入队列。
#ifndef T1_H
#define T1_H
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#define MaxSize 10//定义栈中元素的最大个数
typedef char ElemType;
typedef struct{
ElemType data[MaxSize];
int front,rear;//front指向队头元素,rear指向队尾的下一个位置(也就是下一个应该插入的位置
int tag;//0表示出队操作,1表示入队操作,只有在指针相同且是出队操作才表示空,在指针相同的入队操作表示满
}SqQueue;
void InitSqQueue(SqQueue *Q);//初始化
bool EnSqQueue(SqQueue *Q,ElemType x);//入队操作
bool DeSqQueue(SqQueue *Q,ElemType *x);//出队操作
void printfSqQueue(SqQueue Q);//打印队列
bool EmptySqQueue(SqQueue Q);//判断队列是否为空
bool FullSqQueue(SqQueue Q);//队列是否满
#endif
#include "t1.h"
// 若希望循环队列中的元素都得到利用,则需要设置一个标志域tag,并且以tag的值为0或1来区分
// 队头指针front和队尾指针rear相同的队列状态是“空”还是“满”
void InitSqQueue(SqQueue *Q){
(*Q).rear=(*Q).front=0;
(*Q).tag=0;
}
bool EnSqQueue(SqQueue *Q,ElemType x){
if((*Q).rear==(*Q).front&&(*Q).tag==1)//队列满
return false;
(*Q).data[(*Q).rear]=x;
(*Q).rear=((*Q).rear+1)%MaxSize;
(*Q).tag=1;
return true;
}
bool DeSqQueue(SqQueue *Q,ElemType *x){
if((*Q).rear==(*Q).front&&(*Q).tag==0)//队空
return false;
(*Q).tag=0;
*x=(*Q).data[(*Q).front];
(*Q).front=((*Q).front+1)%MaxSize;
return true;
}
bool EmptySqQueue(SqQueue Q){
if(Q.rear==Q.front&&Q.tag==0){
return true;
}
return false;
}
bool FullSqQueue(SqQueue Q){
if(Q.rear==Q.front&&Q.tag==1)
return true;
return false;
}
void printfSqQueue(SqQueue Q){
if(Q.rear==Q.front&&Q.tag==0)
return;
do{
printf("%c<-",Q.data[Q.front]);
Q.tag=0;
Q.front=(Q.front+1)%MaxSize;
}while(Q.rear!=Q.front&&Q.tag==0);
printf("\n");
}
// void test1(){
// SqQueue Q;
// InitSqQueue(&Q);
// ElemType x=0;
// scanf("%d",&x);
// while(x!=999){
// EnSqQueue(&Q,x);
// scanf("%d",&x);
// }
// // printf("%d-%d\n",Q.front,Q.rear);
// printfSqQueue(Q);
// DeSqQueue(&Q,&x);
// printfSqQueue(Q);
// }
// void main(){
// test1();
// }
#include "t1.h"
// K表示客车,H表示货车,QH用来存暂时还不能上船的货车,QK表示暂时还不能上船的货车,Q表示上船的顺序
void boat(char *c){
if(*c=='\0')
return;
SqQueue Q;
SqQueue QK;
SqQueue QH;
int balance=0;//表示当前客车已入船的数量,每4归0
char temp=' ';//临时变量
InitSqQueue(&Q);
InitSqQueue(&QK);
InitSqQueue(&QH);
while(*c&&!FullSqQueue(QH)&&!FullSqQueue(QK)){//分类,是什么车
if(*c=='H'){
EnSqQueue(&QH,*c);
}else{
EnSqQueue(&QK,*c);
}
c++;
}
while(!EmptySqQueue(QK)||!EmptySqQueue(QH)){
while(balance<4&&!EmptySqQueue(QK)){
DeSqQueue(&QK,&temp);
EnSqQueue(&Q,temp);
balance++;
}
if(balance==4&&!EmptySqQueue(QH)){
DeSqQueue(&QH,&temp);
EnSqQueue(&Q,temp);
balance=0;
}
while(EmptySqQueue(QK)&&!EmptySqQueue(QH)){
DeSqQueue(&QH,&temp);
EnSqQueue(&Q,temp);
}
while(EmptySqQueue(QH)&&!EmptySqQueue(QK)){
DeSqQueue(&QK,&temp);
EnSqQueue(&Q,temp);
}
}
printfSqQueue(Q);
}
void test4(){
char c[]="HHHHHHHHHHH";
boat(c);
}
void main(){
test4();
}