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)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...
随机推荐
- linux 关机要点
主要围绕 sync shutdown reboot这几个指令 将数据同步写入硬盘中的挃令: sync:关机前要保存进硬盘.事实上sync也可以被一般账号使用喔!只丌过一般账号用户所更新的硬盘数据就仅有 ...
- epoll的LT模式缺点
本文为原创,转载请注明:http://www.cnblogs.com/gistao/ epoll提供了ET和LT两种模式,网上文章很多,这里只总结下LT模式下的两个缺点 epoll对fd的管理实现是用 ...
- ionic的tabs
<ion-tabs class="tabs-icon-top/bottom(决定这个tabs是置于上面还是底部) tabs-color-active-positive(图标与字体色) ...
- HDU 5446 中国剩余定理+lucas
Unknown Treasure Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- js操作做GridView
一:获取当前选中行的数据 function fun_selectedInfo() { //获取当前鼠标选中元素 var e=event.srcElement; //获取当前元素所在行号 var row ...
- PL-SQL(免安装版本)报错ORA-12154
今天在帮同事安装PL/SQL时,在登陆的时候出现上述错误,从网上找了好多解决方法,但都没有解决问题.对于免安装版本的PL/SQL在登陆是应该先配置好路径:bin\instantclient_11_ ...
- 写一些封装part1 (事件绑定移除,圆形矩形碰撞检测)
var EventHandle = { addEvent:function(ele,type,handle){ if (ele.addEventListener) { ele.addEventList ...
- android共享内存
在android下不能通过shm_open使用共享内存. 网上有好多关于android下使用Ashmem实现共享内存的,但经过尝试该方法可以mmap出内存,但是和另一个进程没有实现共享. 具体的使用方 ...
- Java中封装、继承和多态
封装: 封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度. 适当的封装可以让程式码更容易理解和维护,也加强了程式码的安全性. 访问修饰符有public,private,prot ...
- 酷炫ILOVEU
assume cs:code code segment main: ;显示背景22*80 ;dh中放行号 ;dl中放列号 bibi: push cx ;显示光标 ;第0页 int 10h ;在光标处显 ...