数据结构之队列

问题引入:

某银行只有两个接待窗口,VIP 窗口和普通窗口,VIP 用户进入 VIP 窗口排队,剩下的进入普通窗口排队。现有 M 次操作,操作有四种类型,如下:

  • IN name V:表示一名叫 name 的用户到 VIPVIP 窗口排队
  • OUT V:表示 VIPVIP 窗口队头的用户离开排队
  • IN name N:表示一名叫 name 的用户到普通窗口排队
  • OUT N:表示普通窗口队头的用户离开排队

求 M 次操作结束后 VIP 窗口队列和普通窗口队列中的姓名。

输出描述

输出 M 次操作后 VIP 窗口队列和普通窗口队列中的姓名(从头到尾),先输出 VIP 窗口队列后输出普通窗口队列。

输入输出样例

示例 1

输入

5
IN xiaoming N
IN Adel V
IN laozhao N
OUT N
IN CLZ V

输出

Adel
CLZ
laozhao

  • 普通队列实现

import java.util.Scanner;

public class 普通队列 {

	static String Vqueue[] = new String[1000];//V队列
	static int Vhead = 0;//首指针指向头元素
	static int Vtail = 0;//尾指针不指向元素,前一个指针指向尾元素
	
	static String Nqueue[] = new String[1000];//N队列
	static int Nhead = 0;//首指针
	static int Ntail = 0;//尾指针
	
	//入队
	static void in(String name, String type) {
		if(type.contains("V")) {//V队列
			Vqueue[Vtail] = name;
			Vtail++;
		}else {//N队列
			Nqueue[Ntail] = name;
			Ntail++;//队列添加一个元素,尾指针加一,但尾指针指向的元素为空
		}
	}
	
	//出队
	static boolean out(String type) {
		if(type.contains("V")) {
			if(Vhead == Vtail) {//V队列为空,不能出队
				return false;
			}else {
				Vhead++;//头指针后移,相当于头指针前都是无效数据,相当于已删除
				return true;
			}
		}else {
			if(Nhead == Ntail) {
				return false;
			}else {
				Nhead++;
				return true;
			}
		}
	}
	
	//获取头元素
	static String getHead(String type) {
		if(type.contains("V")) {
			return Vqueue[Vhead];//头元素所指向的就是第一个元素
		}else {
			return Nqueue[Nhead];
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int M;//一共进行M次操作
		Scanner in = new Scanner(System.in);
		M = in.nextInt();
		while(M > 0) {
			M--;
			String op, name, type;
			op = in.next();
			if(op.contains("IN")) {
				name = in.next();
				type = in.next();
				in(name, type);
			}else {
				type = in.next();
				out(type);
			}
		}
		//依次输出队列中剩下的元素
		String s = getHead("V");
		while(out("V")) {
			System.out.println(s);
			s = getHead("V");
		}
		s = getHead("N");
		while(out("N")) {
			System.out.println(s);
			s = getHead("N");
		}
	}

}
  • 循环队列实现

上述用数组实现的队列太浪费空间了,出队后的空间就废弃了,极大的浪费了空间。怎么样能让数组末尾的指针再次指向数组开头?(取模运算)

  • tail=(tail+1)% MAXSIZE

  • head=(head+1) % MAZSIZE

这样处理后,可以实现逻辑上的环形数组,充分利用了已有空间。

队满:(tail+1) % MAXSIZE == head   (这里牺牲了一个空间)

对空:head == tail


import java.util.Scanner;

public class 循环队列 {

	static int QueueSize = 10005;
	static String Vqueue[] = new String[QueueSize];//V队列
	static int Vhead = 0;//首指针不指向元素,从下一个指针开始指向头元素
	static int Vtail = 0;//尾指针指向尾元素
	
	static String Nqueue[] = new String[QueueSize];//N队列
	static int Nhead = 0;
	static int Ntail = 0;
	
	//入队
	static Boolean in(String name, String type) {
		if(type.contains("V")) {//V队列
			if((Vtail+1) % QueueSize == Vhead) {//队满则不能添加元素
				return false;
			}else {
				Vtail = (Vtail+1) % QueueSize;
				Vqueue[Vtail] = name;//尾指针指向的位置有元素,头指针指向的下一个位置才有元素
				return true;
			}
			
		}else {//N队列
			if((Ntail+1) % QueueSize == Nhead) {
				return false;
			}else {
				Ntail=(Ntail+1) % QueueSize;
				Nqueue[Ntail] = name;
				return true;
			}
		}
	}
	
	//出队
	static boolean out(String type) {
		if(type.contains("V")) {
			if(Vhead == Vtail) {//V队列为空,不能出队
				return false;
			}else {
				Vhead = (Vhead+1) % QueueSize;//循环到末尾直接到前面
				return true;
			}
		}else {
			if(Nhead == Ntail) {
				return false;
			}else {
				Nhead=(Nhead+1) % QueueSize;
				return true;
			}
		}
	}
	
	//获取头元素
	static String getHead(String type) {
		if(type.contains("V")) {
			if(Vhead == Vtail) {
				return "";//空队列返回空
			}else {
				return Vqueue[Vhead+1];//头指针没有指向元素,后一个指针才有元素
			}
		}else {
			if(Nhead == Ntail) {
				return "";//空队列返回空
			}else {
				return Nqueue[Nhead+1];
			}
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int M;//一共进行M次操作
		Scanner in = new Scanner(System.in);
		M = in.nextInt();
		while(M > 0) {
			M--;
			String op, name, type;
			op = in.next();
			if(op.contains("IN")) {
				name = in.next();
				type = in.next();
				in(name, type);
			}else {
				type = in.next();
				out(type);
			}
//			System.out.println(Arrays.toString(Vqueue));
//			System.out.println(Arrays.toString(Nqueue));
		}
		//依次输出队列中剩下的元素
		String s = getHead("V");
		while(out("V")) {
			System.out.println(s);
			s = getHead("V");
		}
		s = getHead("N");
		while(out("N")) {
			System.out.println(s);
			s = getHead("N");
		}
	}


}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值