1 Queue 2 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Text; 7 using System.Threading; 8 9 namespace DataStructure 10 { 11 /// <summary> 12 /// 队列接口 13 /// </summary> 14 interface IQueue<T> 15 { 16 void EnQueue(T elem); //入队列操作 17 T DeQueue(); //出队列操作 18 T GetFront(); //取对头元素 19 int GetLength(); //求队列的长度 20 bool IsEmpty(); //判断队列是否为空 21 void Clear(); //清空队列 22 bool IsFull(); //判断队列是否为满 23 } 24 25 /// <summary> 26 /// 银行队列接口 27 /// </summary> 28 interface IBankQueue : IQueue<int> 29 { 30 int GetCallnumber(); //获取服务号码 31 } 32 33 34 /// <summary> 35 /// 循环顺序队列 36 /// </summary> 37 /// <typeparam name="T"></typeparam> 38 class CSeqQueue<T> : IQueue<T> 39 { 40 private int maxsize; //循环顺序队列的容量 41 private T[] data; //数组,用于存储循环顺序队列中的数据元素 42 private int front; //指示最近一个已经离开队列的元素所占有的位置 循环顺序队列的对头 43 private int rear; //指示最近一个进入队列的元素的位置 循环顺序队列的队尾 44 45 public T this[int index] 46 { 47 get { return data[index]; } 48 set { data[index] = value; } 49 } 50 51 //容量属性 52 public int Maxsize 53 { 54 get { return maxsize; } 55 set { maxsize = value; } 56 } 57 58 //对头指示器属性 59 public int Front 60 { 61 get { return front; } 62 set { front = value; } 63 } 64 65 //队尾指示器属性 66 public int Rear 67 { 68 get { return rear; } 69 set { rear = value; } 70 } 71 72 public CSeqQueue() 73 { 74 75 } 76 77 public CSeqQueue(int size) 78 { 79 data = new T[size]; 80 maxsize = size; 81 front = rear = -1; 82 } 83 84 //判断循环顺序队列是否为满 85 public bool IsFull() 86 { 87 if ((front == -1 && rear == maxsize - 1) || (rear + 1) % maxsize == front) 88 return true; 89 else 90 return false; 91 } 92 93 //清空循环顺序列表 94 public void Clear() 95 { 96 front = rear = -1; 97 } 98 99 //判断循环顺序队列是否为空 100 public bool IsEmpty() 101 { 102 if (front == rear) 103 return true; 104 else 105 return false; 106 } 107 108 //入队操作 109 public void EnQueue(T elem) 110 { 111 if (IsFull()) 112 { 113 Console.WriteLine("Queue is Full !"); 114 return; 115 } 116 rear = (rear + 1) % maxsize; 117 data[rear] = elem; 118 } 119 120 //出队操作 121 public T DeQueue() 122 { 123 if (IsEmpty()) 124 { 125 Console.WriteLine("Queue is Empty !"); 126 return default(T); 127 } 128 front = (front + 1) % maxsize; 129 return data[front]; 130 } 131 132 //获取对头数据元素 133 public T GetFront() 134 { 135 if (IsEmpty()) 136 { 137 Console.WriteLine("Queue is Empty !"); 138 return default(T); 139 } 140 return data[(front + 1) % maxsize];//front从-1开始 141 } 142 143 //求循环顺序队列的长度 144 public int GetLength() 145 { 146 return (rear - front + maxsize) % maxsize; 147 } 148 } 149 150 /// <summary> 151 /// 链队列结点类 152 /// </summary> 153 /// <typeparam name="T"></typeparam> 154 class QueueNode<T> 155 { 156 private T data; //数据域 157 private QueueNode<T> next; //引用域 158 159 public QueueNode(T val, QueueNode<T> p) 160 { 161 data = val; 162 next = p; 163 } 164 165 public QueueNode(QueueNode<T> p) 166 { 167 next = p; 168 } 169 170 public QueueNode(T val) 171 { 172 data = val; 173 next = null; 174 } 175 176 public QueueNode() 177 { 178 data = default(T); 179 next = null; 180 } 181 182 //数据域属性 183 public T Data 184 { 185 get { return data; } 186 set { data = value; } 187 } 188 189 //引用域属性 190 public QueueNode<T> Next 191 { 192 get { return next; } 193 set { next = value; } 194 } 195 } 196 197 /// <summary> 198 /// 链队列类 199 /// </summary> 200 /// <typeparam name="T"></typeparam> 201 class LinkQueue<T> : IQueue<T> 202 { 203 private QueueNode<T> front; //队列头指示器 204 private QueueNode<T> rear; //队列尾指示器 205 private int size; //队列结点个数 206 207 //队列属性 208 public QueueNode<T> Front 209 { 210 get { return front; } 211 set { front = value; } 212 } 213 214 public QueueNode<T> Rear 215 { 216 get { return rear; } 217 set { rear = value; } 218 } 219 220 public int Size 221 { 222 get { return size; } 223 set { size = value; } 224 } 225 226 //初始化链队列 227 public LinkQueue() 228 { 229 front = rear = null; 230 size = 0; 231 } 232 233 public int GetLength() 234 { 235 return size; 236 } 237 238 public void Clear() 239 { 240 front = rear = null; 241 size = 0; 242 } 243 244 public bool IsEmpty() 245 { 246 if ((front == rear) && (size == 0)) 247 return true; 248 else 249 return false; 250 251 } 252 253 //链队列没有容量限制 返回false 254 public bool IsFull() 255 { 256 return false; 257 } 258 259 //入队操作 260 public void EnQueue(T item) 261 { 262 QueueNode<T> q = new QueueNode<T>(item); 263 if (IsEmpty()) 264 { 265 front = q; 266 rear = q; 267 } 268 else 269 { 270 rear.Next = q; 271 rear = q; 272 } 273 ++size; 274 } 275 276 //出对操作 277 public T DeQueue() 278 { 279 if (IsEmpty()) 280 { 281 Console.WriteLine("Queue is Empty !"); 282 return default(T); 283 } 284 QueueNode<T> p = front; 285 front = front.Next; 286 287 if (front == null) 288 { 289 rear = null; 290 } 291 --size; 292 return p.Data; 293 } 294 295 //获取链队列头结点的值 296 public T GetFront() 297 { 298 if (IsEmpty()) 299 { 300 Console.WriteLine("Queue is Empty !"); 301 return default(T); 302 } 303 return front.Data; 304 } 305 306 } 307 308 309 /// <summary> 310 /// 银行叫号链队列类 311 /// </summary> 312 class LinkBankQueue : LinkQueue<int>, IBankQueue 313 { 314 private int callnumber; 315 316 public int Callnumber 317 { 318 get { return callnumber; } 319 set { callnumber = value; } 320 } 321 322 //获取服务号码 323 public int GetCallnumber() 324 { 325 if ((IsEmpty()) && callnumber == 0) 326 { 327 callnumber = 1; 328 } 329 else 330 callnumber++; 331 return callnumber; 332 } 333 } 334 335 /// <summary> 336 /// 银行叫号顺序队列类 337 /// </summary> 338 class CSeqBankQueue : CSeqQueue<int>, IBankQueue 339 { 340 private int callnumber; //记录系统自动产生的新来顾客的服务号码 341 342 public int Callnumber 343 { 344 get { return callnumber; } 345 set { callnumber = value; } 346 } 347 348 public CSeqBankQueue() 349 { 350 351 } 352 353 public CSeqBankQueue(int size) 354 : base(size) 355 { 356 357 } 358 359 //获得服务号码 360 public int GetCallnumber() 361 { 362 if ((IsEmpty()) && callnumber == 0) 363 { 364 callnumber = 1; 365 } 366 else 367 { 368 callnumber++; 369 } 370 return callnumber; 371 } 372 } 373 374 /// <summary> 375 /// 服务窗口类 376 /// </summary> 377 class ServiceWindow 378 { 379 IBankQueue bankQ; 380 381 //服务队列属性 382 public IBankQueue BankQ 383 { 384 get { return bankQ; } 385 set { bankQ = value; } 386 } 387 388 public void Service() 389 { 390 while (true) 391 { 392 Thread.Sleep(10000); 393 if (!bankQ.IsEmpty()) 394 { 395 Console.WriteLine(); 396 lock (bankQ) 397 { 398 Console.WriteLine("请{0}号到{1}号窗口!", bankQ.DeQueue(), Thread.CurrentThread.Name); 399 } 400 } 401 } 402 } 403 } 404 405 class Queue 406 { 407 408 static void Main() 409 { 410 IBankQueue bankQueue = null; 411 Console.WriteLine("请选择存储结构的类型:1.顺序队列 2.链队列:"); 412 char selectFlag = Convert.ToChar(Console.ReadLine()); 413 switch (selectFlag) 414 { 415 /*初始化顺序队列*/ 416 case '1': 417 int count; //接受循环顺序队列的容量 418 Console.WriteLine("请输入队列可容纳的人数:"); 419 count = Convert.ToInt32(Console.ReadLine()); 420 bankQueue = new CSeqBankQueue(count); 421 break; 422 /*初始化链队列*/ 423 case '2': 424 bankQueue = new LinkBankQueue(); 425 break; 426 427 } 428 int windowcount = 4; //设置银行柜台的服务窗口数 429 430 ServiceWindow[] sw = new ServiceWindow[windowcount]; 431 Thread[] swt = new Thread[windowcount]; 432 for (int i = 0; i < windowcount; i++) 433 { 434 sw[i] = new ServiceWindow(); 435 sw[i].BankQ = bankQueue; 436 swt[i] = new Thread(new ThreadStart(sw[i].Service)); 437 swt[i].Name = "" + (i + 1); 438 swt[i].Start(); 439 } 440 while (true) 441 { 442 Console.WriteLine("请点击触摸屏获取号码:"); 443 Console.ReadLine(); 444 445 int callnumber; 446 if (!bankQueue.IsFull()) 447 { 448 callnumber = bankQueue.GetCallnumber(); 449 Console.WriteLine("您的号码是:{0},您前面有{1}位,请等待!", callnumber, bankQueue.GetLength()); 450 bankQueue.EnQueue(callnumber); 451 } 452 else 453 Console.WriteLine("现在业务繁忙,请稍后再来!"); 454 Console.WriteLine(); 455 } 456 } 457 } 458 }