C#实现队列
队列(Queue)是插入操作限定在表的尾部而其他操作限定在表的头部进行的线性表。把进行插入操作的表尾称为队尾(Rear).把进行其他操作的头部称为队头(Front).
队列的操作使按照先进先出后进后出的原则进行的。
用一片连续的存储空间来存储队列中的数据元素,称为顺序队列(Sequence Queue)。类似于顺序表,用一维数组来存放队列中的数据元素。
解决顺序队列的假溢出的方法是将顺序队列看成是首位相接的循环结构,叫循环顺序队列(Circular sequence Queue)。
队列的另外一种存储方式是链式存储,称为链队列(Linked Queue)。通常用单链表表示。
Queue using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; namespace DataStructure
{
/// <summary>
/// 队列接口
/// </summary>
interface IQueue<T>
{
void EnQueue(T elem); //入队列操作
T DeQueue(); //出队列操作
T GetFront(); //取对头元素
int GetLength(); //求队列的长度
bool IsEmpty(); //判断队列是否为空
void Clear(); //清空队列
bool IsFull(); //判断队列是否为满
} /// <summary>
/// 银行队列接口
/// </summary>
interface IBankQueue : IQueue<int>
{
int GetCallnumber(); //获取服务号码
} /// <summary>
/// 循环顺序队列
/// </summary>
/// <typeparam name="T"></typeparam>
class CSeqQueue<T> : IQueue<T>
{
private int maxsize; //循环顺序队列的容量
private T[] data; //数组,用于存储循环顺序队列中的数据元素
private int front; //指示最近一个已经离开队列的元素所占有的位置 循环顺序队列的对头
private int rear; //指示最近一个进入队列的元素的位置 循环顺序队列的队尾 public T this[int index]
{
get { return data[index]; }
set { data[index] = value; }
} //容量属性
public int Maxsize
{
get { return maxsize; }
set { maxsize = value; }
} //对头指示器属性
public int Front
{
get { return front; }
set { front = value; }
} //队尾指示器属性
public int Rear
{
get { return rear; }
set { rear = value; }
} public CSeqQueue()
{ } public CSeqQueue(int size)
{
data = new T[size];
maxsize = size;
front = rear = -;
} //判断循环顺序队列是否为满
public bool IsFull()
{
if ((front == - && rear == maxsize - ) || (rear + ) % maxsize == front)
return true;
else
return false;
} //清空循环顺序列表
public void Clear()
{
front = rear = -;
} //判断循环顺序队列是否为空
public bool IsEmpty()
{
if (front == rear)
return true;
else
return false;
} //入队操作
public void EnQueue(T elem)
{
if (IsFull())
{
Console.WriteLine("Queue is Full !");
return;
}
rear = (rear + ) % maxsize;
data[rear] = elem;
} //出队操作
public T DeQueue()
{
if (IsEmpty())
{
Console.WriteLine("Queue is Empty !");
return default(T);
}
front = (front + ) % maxsize;
return data[front];
} //获取对头数据元素
public T GetFront()
{
if (IsEmpty())
{
Console.WriteLine("Queue is Empty !");
return default(T);
}
return data[(front + ) % maxsize];//front从-1开始
} //求循环顺序队列的长度
public int GetLength()
{
return (rear - front + maxsize) % maxsize;
}
} /// <summary>
/// 链队列结点类
/// </summary>
/// <typeparam name="T"></typeparam>
class QueueNode<T>
{
private T data; //数据域
private QueueNode<T> next; //引用域 public QueueNode(T val, QueueNode<T> p)
{
data = val;
next = p;
} public QueueNode(QueueNode<T> p)
{
next = p;
} public QueueNode(T val)
{
data = val;
next = null;
} public QueueNode()
{
data = default(T);
next = null;
} //数据域属性
public T Data
{
get { return data; }
set { data = value; }
} //引用域属性
public QueueNode<T> Next
{
get { return next; }
set { next = value; }
}
} /// <summary>
/// 链队列类
/// </summary>
/// <typeparam name="T"></typeparam>
class LinkQueue<T> : IQueue<T>
{
private QueueNode<T> front; //队列头指示器
private QueueNode<T> rear; //队列尾指示器
private int size; //队列结点个数 //队列属性
public QueueNode<T> Front
{
get { return front; }
set { front = value; }
} public QueueNode<T> Rear
{
get { return rear; }
set { rear = value; }
} public int Size
{
get { return size; }
set { size = value; }
} //初始化链队列
public LinkQueue()
{
front = rear = null;
size = ;
} public int GetLength()
{
return size;
} public void Clear()
{
front = rear = null;
size = ;
} public bool IsEmpty()
{
if ((front == rear) && (size == ))
return true;
else
return false; } //链队列没有容量限制 返回false
public bool IsFull()
{
return false;
} //入队操作
public void EnQueue(T item)
{
QueueNode<T> q = new QueueNode<T>(item);
if (IsEmpty())
{
front = q;
rear = q;
}
else
{
rear.Next = q;
rear = q;
}
++size;
} //出对操作
public T DeQueue()
{
if (IsEmpty())
{
Console.WriteLine("Queue is Empty !");
return default(T);
}
QueueNode<T> p = front;
front = front.Next; if (front == null)
{
rear = null;
}
--size;
return p.Data;
} //获取链队列头结点的值
public T GetFront()
{
if (IsEmpty())
{
Console.WriteLine("Queue is Empty !");
return default(T);
}
return front.Data;
} } /// <summary>
/// 银行叫号链队列类
/// </summary>
class LinkBankQueue : LinkQueue<int>, IBankQueue
{
private int callnumber; public int Callnumber
{
get { return callnumber; }
set { callnumber = value; }
} //获取服务号码
public int GetCallnumber()
{
if ((IsEmpty()) && callnumber == )
{
callnumber = ;
}
else
callnumber++;
return callnumber;
}
} /// <summary>
/// 银行叫号顺序队列类
/// </summary>
class CSeqBankQueue : CSeqQueue<int>, IBankQueue
{
private int callnumber; //记录系统自动产生的新来顾客的服务号码 public int Callnumber
{
get { return callnumber; }
set { callnumber = value; }
} public CSeqBankQueue()
{ } public CSeqBankQueue(int size)
: base(size)
{ } //获得服务号码
public int GetCallnumber()
{
if ((IsEmpty()) && callnumber == )
{
callnumber = ;
}
else
{
callnumber++;
}
return callnumber;
}
} /// <summary>
/// 服务窗口类
/// </summary>
class ServiceWindow
{
IBankQueue bankQ; //服务队列属性
public IBankQueue BankQ
{
get { return bankQ; }
set { bankQ = value; }
} public void Service()
{
while (true)
{
Thread.Sleep();
if (!bankQ.IsEmpty())
{
Console.WriteLine();
lock (bankQ)
{
Console.WriteLine("请{0}号到{1}号窗口!", bankQ.DeQueue(), Thread.CurrentThread.Name);
}
}
}
}
} class Queue
{ static void Main()
{
IBankQueue bankQueue = null;
Console.WriteLine("请选择存储结构的类型:1.顺序队列 2.链队列:");
char selectFlag = Convert.ToChar(Console.ReadLine());
switch (selectFlag)
{
/*初始化顺序队列*/
case '':
int count; //接受循环顺序队列的容量
Console.WriteLine("请输入队列可容纳的人数:");
count = Convert.ToInt32(Console.ReadLine());
bankQueue = new CSeqBankQueue(count);
break;
/*初始化链队列*/
case '':
bankQueue = new LinkBankQueue();
break; }
int windowcount = ; //设置银行柜台的服务窗口数 ServiceWindow[] sw = new ServiceWindow[windowcount];
Thread[] swt = new Thread[windowcount];
for (int i = ; i < windowcount; i++)
{
sw[i] = new ServiceWindow();
sw[i].BankQ = bankQueue;
swt[i] = new Thread(new ThreadStart(sw[i].Service));
swt[i].Name = "" + (i + );
swt[i].Start();
}
while (true)
{
Console.WriteLine("请点击触摸屏获取号码:");
Console.ReadLine(); int callnumber;
if (!bankQueue.IsFull())
{
callnumber = bankQueue.GetCallnumber();
Console.WriteLine("您的号码是:{0},您前面有{1}位,请等待!", callnumber, bankQueue.GetLength());
bankQueue.EnQueue(callnumber);
}
else
Console.WriteLine("现在业务繁忙,请稍后再来!");
Console.WriteLine();
}
}
}
}
C#实现队列的更多相关文章
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- 消息队列 Kafka 的基本知识及 .NET Core 客户端
前言 最新项目中要用到消息队列来做消息的传输,之所以选着 Kafka 是因为要配合其他 java 项目中,所以就对 Kafka 了解了一下,也算是做个笔记吧. 本篇不谈论 Kafka 和其他的一些消息 ...
- Beanstalkd一个高性能分布式内存队列系统
高性能离不开异步,异步离不开队列,内部是Producer-Consumer模型的原理. 设计中的核心概念: job:一个需要异步处理的任务,是beanstalkd中得基本单元,需要放在一个tube中: ...
- .net 分布式架构之业务消息队列
开源QQ群: .net 开源基础服务 238543768 开源地址: http://git.oschina.net/chejiangyi/Dyd.BusinessMQ ## 业务消息队列 ##业务消 ...
- 【原创经验分享】WCF之消息队列
最近都在鼓捣这个WCF,因为看到说WCF比WebService功能要强大许多,另外也看了一些公司的招聘信息,貌似一些中.高级的程序员招聘,都有提及到WCF这一块,所以,自己也关心关心一下,虽然目前工作 ...
- 缓存、队列(Memcached、redis、RabbitMQ)
本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...
- Java消息队列--ActiveMq 实战
1.下载安装ActiveMQ ActiveMQ官网下载地址:http://activemq.apache.org/download.html ActiveMQ 提供了Windows 和Linux.Un ...
- Java消息队列--JMS概述
1.什么是JMS JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送 ...
- 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)
Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...
- [数据结构]——链表(list)、队列(queue)和栈(stack)
在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...
随机推荐
- Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目
Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目 新建一个maven工程,这里不赘述如何新建maven工程. 添加Neo4j jar到你的工程 有两种方 ...
- myeclipse里的调试快捷键
好多时候在调试代码时,有的时候只会用F5,其他的快捷键却一概不知.今天百度查了一下其他快捷键调试的作用,总结如下 F5 (setp into ): 跳入当前执行的方法中 F6 (step over): ...
- Swift处理堆栈问题——给定两组序列,其中一个序列表示栈的push 顺序,判断另一个序列有没有可能是对应的pop 顺序
题目:输入两个整数序列.其中一个序列表示栈的push 顺序,判断另一个序列有没有可能是对应的pop 顺序.为了简单起见,我们假设push 序列的任意两个整数都是不相等的.比如输入的push 序列是1. ...
- CentOS6.5上Oracle11gR2静默安装
一.环境准备环境 操作系统:CentOS release 6.5 (Final) 内核版本:2.6.32-431.el6.x86_64 物理内存:2G(必须大于1G) swap分区:3G(必须大于3G ...
- shh(struts+spring+Hibernate)的搭建
一.Struts 一.struts的流程 (1)首先,用户在地址栏中输入你的项目访问路径,然后这个请求会发送到服务器,服务器先找到要web.xml的,给web.xml中配置了一个filter过滤器,过 ...
- js中substr,substring,indexOf,lastIndexOf,split 的用法
1.substr substr(start,length)表示从start位置开始,截取length长度的字符串. var src="images/off_1.png";alert ...
- Windows下面如何建立多个Django虚拟环境
Linux 安装请见另一篇博客 http://www.cnblogs.com/zhaoyingjie/p/6180758.html 1.安装 virtualenv 2.安装virtualenvwrap ...
- JavaScriptPolyfillShim 在JavaScript中Shim和Polyfill有什么区别?
在JavaScript的世界里,有两个词经常被提到,那就是Shim和Polyfill,它们指的都是什么,又有什么区别?在本文中,将简短的给大家介绍他们之间的联系和区别.Shim一个shim就是一个库, ...
- golang开发环境(2016.9.16)
一.windows下安装 1.下载go1.7.3.windows-amd64.msi,建议默认安装到‘C:\Go\’ 2.环境变量 变量 值 说明 Path C:\Go\bin 安装程序默认会设置,如 ...
- 如何给Visual Studio 2015安装XNA4.0
从这个地址下载安装包 https://mxa.codeplex.com/releases/view/618279 按照说明步骤依次安装 DirectX XNA Framework 4.0 Redist ...