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系统上通知网关更新arp
经常会有在线更换Linux服务器IP的操作,该操作带来的一个问题是: 我们已经执行了修改IP的操作,但由于网络上(网关)的ARP缓存暂未更新,导致在某一段时间内,该服务器会有网络不通的情况存在. 因此 ...
- 蓝牙-HCI错误码列表
错误码定义: /* Success code */ #define HCI_SUCCESS 0x00 /* Possible error codes */ #define HCI_UNKNOWN_HC ...
- web发布 将各个文件夹输出合并到其自己的程序集 注意事项
今天在发布web网站的时候 使用了“将各个文件夹输出合并到其自己的程序集”的选项,如图: 开始在 程序集前缀(可选)处,没有填写内容. 发布到IIS后出现未加载到程序集xxxx的错误. 经过各种调试, ...
- KANO模型
一.满意度的定义 消费者的满意度是取决于他们对企业所提供的产品和服务的事前期待,与实际(感知)效果之间的比较后,用户形成的开心或失望的感觉.就是说,如果购后在实际消费中的实际效果与事前期待相符合,则感 ...
- PS中的图像知识
图像处理对于前端工作来说是一个不能回避的问题,ps技术也是我们必备的技能.用法可以在使用中不断的熟练,但针对前端技术本身的一些知识点,需要我们平时不断的积累才能够在使用中不出现问题. 如今的办公,已经 ...
- js或jquery如何获取父级、子级、兄弟元素(包括祖级、孙级等)
原生javascript方法: var a = document.getElementById("dom"); del_space(a); //清理空格 var b = a.chi ...
- linux下安装nodejs
之前安装过windows下的node,感觉还是很方便的,不成想今天安装linux下的坑了老半天,特此记录. 1. 下载node.js,官方有提供源码版本和编译版的,方便起见我使用编译版的,下载后解压缩 ...
- EXCEL导入(反射)
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...
- 简易c语言文法
<程序>→<外部声明>|<程序><外部声明> <外部声明>→<函数定义>|<声明> <函数定义>→< ...
- 差分:IncDec Sequence 差分数组
突然就提到了这个东西,为了不再出现和去年联赛看见二分没学二分痛拿二等第一的情况,就去学了一下,基础还是比较简单的-- 先看一个经典例题: 给定一个长度为n的数列{a1,a2...an},每次可以选择一 ...