11. C#数据结构与算法 -- 顺序队列

理论基础:

队列(Queue)是插入操作限定在表的尾部而其它操作限定在表的头部进行的线性表。把进行插入操作的表尾称为队尾(Rear),把进行其它操作的头部称为队头(Front)。

对列的操作是按照先进先出(First In First Out)或后进后出( Last In Last Out)的原则进行的,因此,队列又称为FIFO表或LILO表。

与栈一样,队列的运算是定义在逻辑结构层次上的,而运算的具体实现是建立在物理存储结构层次上的。因此,把队列的操作作为逻辑结构的一部分,每个操作的具体实现只有在确定了队列的存储结构之后才能完成。

队列可以区分为顺序队列,链队列两种。

顺序队列类似于顺序栈,用一维数组来存放顺序队列中的数据元素。链队列同链栈一样,链队列通常用单链表来表示,它的实现是单链表的简化。

顺序队列在操作的过程中会出现“假溢出”。可以用循环顺序队列解决这种现象。

C#实现:

1 接口定义

C#语言的泛型接口来表示队列,接口中的方法成员表示基本操作。为了表示的方便与简洁,把泛型队列接口取名为IQueue<T>(实际上,在C#中泛型队列类是从IEnumerable<T>、ICollection和IEnumerable接口继承而来,没有IQueue<T>泛型接口)。
         队列接口IQueue<T>的定义如下所示:

public interface IQueue<T>
    {
        /// <summary>
        /// 队列长度
        /// </summary>
        /// <returns></returns>
        int GetLength();
        /// <summary>
        /// 判断是否为空
        /// </summary>
        /// <returns></returns>
        bool IsEmpty();
        /// <summary>
        /// 是否已满
        /// </summary>
        /// <returns></returns>
        bool Full();
        /// <summary>
        /// 清空队列
        /// </summary>
        void Clear();
        /// <summary>
        /// 入队
        /// </summary>
        /// <param name="item"></param>
        void In(T item);
        /// <summary>
        /// 出队
        /// </summary>
        /// <returns></returns>
        T Out();
        
    }

 2 代码实现

实现提供的接口

public 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(int size)
        {
            data =new T[size];
            maxsize = size;
            front = rear = -1;
        }

        //队列长度
        public int GetLength()
        {
            return (rear - front + maxsize) % maxsize;
        }
        //清空队列
        public void Clear()
        {
            front = rear = -1;
        }
        //判断是否为空
        public bool IsEmpty()
        {
            if (front == rear)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //判断是否已满
        public bool IsFull()
        {
            if (front == (rear+1)%maxsize)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //入队
        public void In(T item)
        {
            if (IsFull())
            {
                Console.Write("Queue is full");
                return;
            }

            data[++rear] = item;
        }
        //出队
        public T Out()
        {
            if (IsEmpty())
            {
                Console.Write("Queue is empty");
                return;
             }
             return data[++front];
        }
    }

C#中的队列:

C#2.0以下版本只提供了非泛型的Queue类,该类继承了ICollection、IEnumerable和ICloneable接口。

C#2.0提供了泛型的Queue<T>类,该类继承了IEnumerable<T>、ICollection和IEnumerable接口。

以下程序说明了泛型Queue<T>类的主要方法,并对在我们自定义的队列类中没有出现的成员方法进行了注释,

关于泛型Queue<T>类的更具体的信息,可参考.NET Framework的有关书籍。

public class Queue<T> : IEnumerable<T>, ICollection, IEnumerable
    {
        public void Clear();
        //确定某元素是否在Queue<T>中。
        //如果在Queue<T> 中找到 item,则为true;否则为false。
        public bool Contains(T item);//从指定数组索引开始将Queue<T>元素复制到现有一维Array 中。
        public void CopyTo(T[] array, int arrayIndex);
        //移除并返回位于Queue<T>开始处的对象。
        //从Queue<T>的开头移除的对象。
        public T Dequeue();
        //返回位于Queue<T>开始处的对象但不将其移除。
        public T Peek();
        //将Queue<T>元素复制到新数组。
        public T[] ToArray();
        //如果元素数小于当前容量的90%,
        //将容量设置为Queue<T> 中的实际元素数。
        public void TrimExcess();
    }

队列通常记为:Q= (a1,a2,…,an),a1为队头元素,an为队尾元素。元素按照a1,a2,…,an的次序依次入队,出队的次序与入队相同,即a1第一个出队,an最后一个出队。所以,对列的操作是按照先进先出(First In First Out)或后进后出( Last In Last Out)的原则进行的,因此,队列又称为FIFO表或LILO表。

队列的常用操作有:

1、构造一个空队列:InitQueue()//在C#中可以使用构造函数来实现

2、清空队列:ClearQueue()

3、判断队列是否为空:IsEmpty()

4、判断队列是否已满:IsFull()

5、求队列长度:QueueLength()

6、入队操作:In()

7、出队操作:Out()

8、得到队头元素:GetHead()

下面给出一个实现顺序队列的源代码:

实例1:

using System;

class Queue
{
    object[] data;  //数据元素
    int maxsize;    //最大容量
    int front;      //指向队头
    int rear;       //指向队尾

    //初始化队列
    public Queue(int size)
{
        this.maxsize = size;
        data = new object[size];
front = rear = -1;
}
    //最大容量属性
    public int MaxSize
{
        get
{
            return this.maxsize;
}
        set
{
            this.maxsize = value;
}
}
    //队尾属性
    public int Rear
{
        get
{
            return this.rear;
}
}
    //队头属性
    public int Front
{
        get
{
            return this.front;
}
}
    //数据属性
    public object this[int index]
{
        get
{
            return data[index];
}
}
    //获得队列的长度
    public int GetQueueLength()
{
        return rear-front;
}
    //判断队列是否满
    public bool IsFull()
{
        if(GetQueueLength() == maxsize)
            return true;
        else
            return false;
}
    //判断队列是否为空
    public bool IsEmpty()
{
        if(rear==front)
            return true;
        else
            return false;
}
    //清空队列
    public void ClearQueue()
{
rear = front = -1;
}
    //入队
    public void In(object e)
{
        if(IsFull())
{
            Console.WriteLine("Queue is full!");
            return;
}
data[++rear]=e;
}
    //出队
    public object Out()
{
        if(IsEmpty())
{
            Console.WriteLine("Queue is empty!");
            return null;
}
        if(rear-front>0)
{
            object tmp = data[++front];
            return tmp;
}
        else
{
            Console.WriteLine("All queue numbers are dequeued!");
ClearQueue();
            return null;
}
}
    //获得队头元素
    public object GetHead()
{
        if(IsEmpty())
{
            Console.WriteLine("Queue is empty!");
            return null;
}
        return data[front+1];
}
}
class Test
{
    static void Main()
{
        Queue q = new Queue(1);
        int rdNum;
        Random rd = new Random();
        while(!q.IsFull())
{
rdNum = rd.Next(10,100);
q.In(rdNum);
            Console.WriteLine("{0} Enqueue,the numbers of the queue is:{1}",rdNum,q.GetQueueLength());
}
        Console.WriteLine("***************************");
        while (!q.IsEmpty())
{
            Console.WriteLine("{0} Dequeue, the number of the queue is:{1}", q.Out(), q.GetQueueLength());
}
        Console.ReadLine();
}
}

实例2:

演示了C#内置的队列如何进行添加,移除等功能。

using System; 
using System.Collections.Generic; 
class Example 
{ 
 public static void Main() 
 { 
  Queue<string> numbers = new Queue<string>(); 
  numbers.Enqueue("one"); 
  numbers.Enqueue("two"); 
  numbers.Enqueue("three"); 
  numbers.Enqueue("four"); 
  numbers.Enqueue("five"); 
  // A queue can be enumerated without disturbing its contents. 
  foreach( string number in numbers ) 
  { 
   Console.WriteLine(number); 
  } 
  Console.WriteLine("\nDequeuing ‘{0}‘", numbers.Dequeue()); 
  Console.WriteLine("Peek at next item to dequeue: {0}",  
   numbers.Peek()); 
  Console.WriteLine("Dequeuing ‘{0}‘", numbers.Dequeue()); 
  // Create a copy of the queue, using the ToArray method and the 
  // constructor that accepts an IEnumerable<T>. 
  Queue<string> queueCopy = new Queue<string>(numbers.ToArray()); 
  Console.WriteLine("\nContents of the first copy:"); 
  foreach( string number in queueCopy ) 
  { 
   Console.WriteLine(number); 
  } 
  // Create an array twice the size of the queue and copy the 
  // elements of the queue, starting at the middle of the  
  // array.  
  string[] array2 = new string[numbers.Count * 2]; 
  numbers.CopyTo(array2, numbers.Count); 
  // Create a second queue, using the constructor that accepts an 
  // IEnumerable(Of T). 
  Queue<string> queueCopy2 = new Queue<string>(array2); 
  Console.WriteLine("\nContents of the second copy, with duplicates and nulls:"); 
  foreach( string number in queueCopy2 ) 
  { 
   Console.WriteLine(number); 
  } 
  Console.WriteLine("\nqueueCopy.Contains(\"four\") = {0}",  
   queueCopy.Contains("four")); 
  Console.WriteLine("\nqueueCopy.Clear()"); 
  queueCopy.Clear(); 
  Console.WriteLine("\nqueueCopy.Count = {0}", queueCopy.Count); 
 } 
} 

/* This code example produces the following output: 
one 
two 
three 
four 
five 
Dequeuing ‘one‘ 
Peek at next item to dequeue: two 
Dequeuing ‘two‘ 
Contents of the copy: 
three 
four 
five 
Contents of the second copy, with duplicates and nulls: 
three 
four 
five 
queueCopy.Contains("four") = True 
queueCopy.Clear() 
queueCopy.Count = 0 
 */

参考:
http://www.jb51.net/article/65151.htm 
http://www.cnblogs.com/Richet/archive/2008/10/20/1315192.html

http://www.biye5u.com/article/Csharp/methprog/2013/6074_2.html

时间: 2024-11-09 23:31:54

11. C#数据结构与算法 -- 顺序队列的相关文章

【Java数据结构学习笔记之二】Java数据结构与算法之队列(Queue)实现

  本篇是数据结构与算法的第三篇,本篇我们将来了解一下知识点: 队列的抽象数据类型 顺序队列的设计与实现 链式队列的设计与实现 队列应用的简单举例 优先队列的设置与实现双链表实现 队列的抽象数据类型   队列同样是一种特殊的线性表,其插入和删除的操作分别在表的两端进行,队列的特点就是先进先出(First In First Out).我们把向队列中插入元素的过程称为入队(Enqueue),删除元素的过程称为出队(Dequeue)并把允许入队的一端称为队尾,允许出的的一端称为队头,没有任何元素的队列

数据结构与算法(六)--队列

一.学习大纲 队列的定义.分类.基本方法 队列的实现代码 队列的底层实现(数组.链表) 队列的的分类:顺序队列.循环队列 二.队列 队列的定义:先进者先出的一种操作受限的线性表数据结构,它包含入队enqueue()和dequeue()两个基本的操作: 作为一种非常基础的数据结构,队列的应用也非常广泛,特别是一些具有某些额外特性的队列,比如循环队列.阻塞队列.并发队列.它们在很多偏底层系统.框架.中间件的开发中,起着关键性的作用.比如高性能队列 Disruptor.Linux 环形缓存,都用到了循

数据结构和算法-007 队列

堆栈,另一个经典的数据结构.先进先出. 直接看代码吧,实现以下功能: 创建队列 插入值 取出值 值查看当前值 顺序插入 public class TheQueue {          private String[] queueArray;          private int queueSize;          private int front, rear, numberOfItems =0;          TheQueue(int size){                

数据结构与算法之队列、栈

除了数组.链表,线性的数据结构中还有很重要的几种结构:队列.栈. 队列,一种先进先出的数据结构(FIFO),其实队列可以看成是一个两个口的管道,从一个口进,另一个口出,先进去的必定得在另一个口先出去,否则后面的都出不去:栈,一种后进先出的数据结构(LIFO),栈更像是只有一个口的管道,只有一个开口可以进出,先进去的在底部,所以必须得让后进去的先出去,它才能出去. 实现队列和栈可以用顺序存储结构,也可以用链式存储结构.这里采用的是链表来实现,同时还有用两个栈实现一个队列和用两个队列实现一个栈的算法

Java数据结构与算法(4) - 队列(Queue和PriorityQ)

队列: 先进先出(FIFO). 优先级队列: 在优先级队列中,数据项按照关键字的值有序,关键字最小的数据项总在对头,数据项插入的时候会按照顺序插入到合适的位置以确保队列的顺序,从后往前将小于插入项的数据项后移.在图的最小生成树算法中应用优先级队列. 示例代码: package chap04.Queue; class Queue { private int maxSize; private long[] queArray; private int front; private int rear;

数据结构与算法——循环队列

今天总结循环队列. 什么是队列? 队列跟栈差不多,也是一种操作受限的线性表,只允许在线性表的一端进行插入操作,在另一端进行删除操作.插入的一端称为队尾,删除的一端称为队头,插入操作称为入队,而删除操作称作出出队,不含任何数据元素的队称为空队.队列也有两种实现方式,一种就是顺序存储,用数组实现,另一种是采用链表形式.今天总结顺序存储的循环队列. 什么是循环队列? 循环队列就是,当队尾指针移动到数组末尾时,下次再有元素入队时,可以将队尾指针重新移到数组前面没有元素的位置. 为什么要使用循环队列? 循

Java数据结构和算法(五)——队列

队列,queqe,就是现实生活中的排队. 1.简单队列: public class Queqe { private int array[]; private int front; private int end; private int number; private int max; private Queqe(int maxsize){ array = new int[maxsize]; max = maxsize; front = 0; end = 0; number = 0; } pri

12. C#数据结构与算法 -- 顺序栈

理论基础: 栈(Stack)是操作限定在表的尾端进行的线性表.表尾由于要进行插入.删除等操作,所以,它具有特殊的含义,把表尾称为栈顶(Top),另一端是固定的,叫栈底(Bottom).当栈中没有数据元素时叫空栈(Empty Stack). 栈可以分为顺序栈和链栈. 用一片连续的存储空间来存储栈中的数据元素,这样的栈称为顺序栈(Sequence Stack).类似于顺序表,用一维数组来存放顺序栈中的数据元素.栈顶指示器top设在数组下标为0的端,top随着插入和删除而变化,当栈为空时,top=-1

数据结构与算法 顺序表 链表

内存 计算机的作用 用来存储和运算二进制的数据 衡量计算机内存大小的单位: bit(位): 字节:8bit kb:1024字节 mb:1024kb 问题:计算机如何计算1+2? 必须先在计算机的内存开辟内存空间 才将对应的数值存储到该内存中 变量的概念 a = 10 在计算机中表示的含义(内存图) 内存空间开辟好了之后,每一块内存空间都会有两个默认的属性 内存空间的大小:算机内存大小的单位 内存空间的地址:十六进制的数值 地址作用:用来定位(追踪)指定内存空间,就可以获取该内存空间中存储的数据