数据结构与算法实践系列文章(六)线性结构之队列

队列
定义

队列是一种先进先出(FIFO)的线性表.在表一端插入在另一端删除

只能在表的一端(队尾)进行插入,在另一端(队头)进行删除运算的线性表

逻辑结构: 与线性表相同,任为一对一关系。

存储结构: 用顺序队列或链队存储均可。

运算规则: 先进先出FIFO

实现方式: 关键是编写入队和出队函数,具体实现实现依顺序队或的不同而不同。

队列的操作
C语言

循环队列
循环队列的定义
循环队列的操作
C语言
#include <stdio.h>
#include <stdlib.h>
struct Queue{
int *data
int capacity; //容量
int front; // 队头
int rear; // 队尾
}
// 指定容量,初始话数据
void init(struct Queue *pq,int capacity){
    pq->capacity = capacity;
    pq->data=(int*)malloc(sizeof(int)*(capacity+1));
    // 初始队头和队尾
    pq->front=pq->rear=0;
}
//队是否满
int isFull(const struct Queue *pq){
    // 取余操作 循环
    if((pq->rear+1)%(pq->capacity+1) == pq->front) return 1;
    else return 0;
}
int isEmpty(const struct Queue *pq){
    return pq->front == pq->rear;
}
//入队
int enQueue(struct Queue *pq,int capacity){
    if(isFull(pq)) return 0;
    else{
        pq->data[pq->rear]=x;
        pq->rear =(pq->rear+1) % (pq->capacity+1);
        return 1;
    }
}
//出队e
int delQueue(struct Queue *pq, int *px){
    if(isEmpty(pq)) return 0;
    else{
        *px = pq->data[pq->front];
        pq->front = (pq->front+1)%(pq->capacity+1);
        return 1;
    }
}
int main(){
    struct Queue q;
    init(&q,5);
    // 入队
    enQueue(&q,11);
    // 出队
    int x;
    delQueue(&q,&x);
    return 0;
}
C++
#include <isostream>
using namespace std;
struct Node{
    int data;
    Node* next;
     Node(int x){
        data=x;
        next=NULL;
    }
}
class Queue{
    // 作为一个私有对象
private:    
    Node* front; // 队头
    Node* rear; // 队尾
   
public:
    Queue(){
        //不带空头节点的链表,空指针
        front = real=NULL;
    }
    // 定义一个析构函数释放内存
    ~Queue(){
        Node* tmp;
        while(front){
            tmp = front;
            front=front->next;
            delete tmp;
        }
    }
    bool isEmpty(){
        return front ==NULL; // front为null就是空
    }
    // 入队
    void enQueue(int x){
        Node *tmp;
        tmp=new Node();
        if(isEmpty()){
            cout << "empty" << tmp->data << endl;
            front=rear=tmp;
        }else{
            // 队列不为空时
            rear->next=tmp;
            rear = rear->next; // 等价于 rear = tmp
        }  
    }
    // 出队
    bool delQueue(int *px){
        // 使用指针
        if(isEmpty()) return false;
        else{
            //获取队首元素
            *px= front->data;
            // 把头节点删除
            Node* tmp;
            tmp = front;
            front = front->next;
            delete tmp;
            // 当出队时为null时 则rear也要为null
            if(front==NULL) rear=NULL;
            return true;
        }
    }
}

int main(int argc,const char *argv[]){
    
    return 0;
}
C++自带的
#include <isostream>
#include <queue>
using namespace std;
int main(int argc,const char *argv[]){
    queue<int> q;
    q.push(11); // 增加元素
    q.push(12);
    q.pop();// 出队
    int x=q.front();// 查看队首元素
    return 0;
}
java
public static void main(String[] args){
    // 链表实现了对例的操作
    Queue<Integer> q= new LinkedList<>();
    q.add(11);
    q.add(12);
    q.add(13);
    System.out.println(q.peek());// 查看队首元素
    System.out.println(q.poll());// 出队
}
简单模拟单队列排队

题目

设某银行有一个固定能容纳N个顾客的等候区,顾客想进银行,若等候区有空则可进,否则被拒绝进入。
每当银行柜员叫号时,等候区中最先进入的顾客离开等候区前往柜台办理业务,若叫号时等候区无人,则此次叫号作废

输入

第一行输入一个不大于20的正整数N,表示银行等候区能容纳的人数,
接下来用若干行表示依时间顺序先后发生的“顾客想进银行”或“叫号”事件,格式分别是:

顾客想进银行,用 In 表示,其中是顾客编号,为不大于100000的正整数; 叫号,用Calling表示。
最后一行是一个#符号,表示输入结束。

输出

顾客想进银行,若顾客进入,则输出 joined. Total: 其中是该顾客的编号,是顾客进入后,等候区的人数
顾客想进银行,若因等候区满而被拒绝,则输出 rejected. 其中是该顾客的编号 叫号,若有顾客前往柜台,则输出
called. Total: 其中是该顾客的编号,是顾客去柜台后,等候区的人数 叫号,等候区无人,则输出 No
one!

C语言
#include <stdio.h>
#include <stdlib.h>
struct Queue{
int *data
int capacity; //容量
int front; // 队头
int rear; // 队尾
int size;
}
// 指定容量,初始话数据
void init(struct Queue *pq,int capacity){
    pq->capacity = capacity;
    pq->data=(int*)malloc(sizeof(int)*(capacity+1));
    // 初始队头和队尾
    pq->front=pq->rear=0;
    pq->size=0;
}
//队是否满
int isFull(const struct Queue *pq){
    // 取余操作 循环
    if((pq->rear+1)%(pq->capacity+1) == pq->front) return 1;
    else return 0;
}
int isEmpty(const struct Queue *pq){
    return pq->front == pq->rear;
}
//入队
int enQueue(struct Queue *pq,int capacity){
    if(isFull(pq)) return 0;
    else{
        pq->data[pq->rear]=x;
        pq->rear =(pq->rear+1) % (pq->capacity+1);
        pq->size++;
        return 1;
    }
}
//出队e
int delQueue(struct Queue *pq, int *px){
    if(isEmpty(pq)) return 0;
    else{
        *px = pq->data[pq->front];
        pq->front = (pq->front+1)%(pq->capacity+1);
        pq->size--;
        return 1;
    }
}
int main(){
   int N;
    scanf("%d",&N);
    struct Queue q;
    init(&q,N);
    char op[20];
    int id;
    scanf("%s",op);
    // 如果op的0号元素不是#
    while(op[0] !='#'){
        if(op[0]=='I'){
            // 如果是IN+id
            scanf("%d",&id);
            if(isFull(&q)){
               // 如果对列满了
                printf("%d rejected.\n",id);
            }else{
                enQueue(&q,id);
                printf("%d joined. Total:%d",id,q.size);
            }
        }else{
            // 如果是Calling+id
            if(isEmpty(&q)){
                printf("No one!\n");
            }else{
                delQueue(&q,&id);
                printf("%d called. Total:%d",id,q.size) 
            }
        }
        scanf("%s",op);
    }
    return 0;
}
C++
#include<stdio.h>
#include<iostream>
#include<queue>
#include<string>

using namespace std;
//总体来说,还是简单的题,队列的简单出队和入队操作 
int main(){
	queue<int> q;
	
	int N;
	string str;
	scanf("%d",&N);
	int tem;
    while(getline(cin,str),str !="0"){
    	tem = 0 ; 
    	if(str[0] == '#') break;         // 结束符
    	else if(str == "Calling"){//叫号
			if(!q.empty()){
				tem = q.front();
				q.pop();
				printf("%d called. Total:%d\n",tem,q.size());
			}else{
				printf("No one!\n");
			}	
		}else{
    		for(int i =0;i<str.length();){
    			if(str[0] == 'I' && str[1] == 'n'){//入队
    				i +=2;
    				if(str[i] == ' ')i++;
    				tem = str[i++] - '0';
    
    				while(i<str.length() && str[i] >= '0' && str[i] <= '9'){
    					tem = tem * 10  + (str[i] - '0');
    					i++;
					}
    				if(q.size() < N){
						q.push(tem);
						printf("%d joined. Total:%d\n",tem,q.size());
					}else{
						printf("%d rejected.\n",tem);
					}
    			
				}
			
			}
		}
	}
	return 0;
}

java
public static void main(String[] args){
    Scanner in = new Scanner(System.in);
    int N= in.next();
    Queue<String> q=new LinkedList();
    String op,id;
    op= in.next();
    while(!op.equals("#")){
        if(op.equals("In")){
            id= in.next();
            if(q.size() == N){
                System.out.println(id+" rejected.");
            }else{
                q.offer(id);
                System.out.println(id+" joined. Total:"+q.size());

            }
        }else{
            if(q.isEmpty()){
                System.out.println("No one!");
            }else{
                id=q.poll();
                System.out.println(id+"called. Total:"+q.size());
            }
        }
        op= in.next();
    }
 in.close();

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kay三石

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值