二、队列
队列,FIFO表,其插入和删除操作分别在两端进行。插入过程称为入队,删除过程称为出队。
队列的几个基本操作:
(1)Queue()
构造一个空队列。
(2)Empty()
判断队空,若空,返回真值,否则返回假值。
(3)Full()
判断队满,若满,返回真值,否者返回假值。
(4)EnQueue(x)
入队,若队列不满,则将元素x插入队尾。
(5)DeQueue()
出队,若队列非空,则删除队首元素,并返回该元素。
(6)GetFront()
若队列非空,返回队首元素,但不删除队首。
微软提供的队列如下:
Code
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();
}
其中IQueue<T>有如下定义:
Code
public interface IQueue<T> {
int GetLength(); //求队列的长度
bool IsEmpty(); //判断对列是否为空
void Clear(); //清空队列
void In(T item); //入队
T Out(); //出队
T GetFront(); //取对头元素
}
写队列就吸取了教训,没有想用.net自带的队列,只是稍微看了下,就自己动手写了队列--myQueue。
Code
using System;
public class myQueue
{
private object[] data;
private int maxsize;
private int front;
private int rear;
public myQueue(int size)
{
data=new object[size];
maxsize=size;
front=rear=0;
}
public object this[int index]
{
get{return data[index];}
set{data[index]=value;}
}
public int MaxSize{get;set;}
public int Front{get;set;}
public int Rear{get;set;}
public void Clear()
{
front=rear=-1;
}
public bool IsEmpty()
{
return front==rear;
}
public bool IsFull()
{
return front==rear%maxsize+1;
}
public bool EnQueue(object e)
{
if(!IsFull())
{
data[rear]=e;
rear=(rear+1)%maxsize;
return true;
}
else
{
Console.Write("队列已满");
return false;
}
}
public object DeQueue()
{
object temp=null;
if(!IsEmpty())
{
temp=data[front];
front=(front+1)%maxsize;
}
return temp;
}
public object GetFront()
{
if(IsEmpty())
{
Console.Write("队列为空");
return default(object);
}
return data[front];
}
public int Length()
{
return (rear-front+maxsize)%maxsize;
}
}
没有注释,非常惭愧。。。。因为写的时候一气呵成,现在也不想补了,将就着用吧。用队列我找的是素数环的题目,开始没有理解,
以为就是简单的判断下素数组成一个环,后来认真仔细分析题目后,才知道要求是让一组数的相邻两数之和为素数,这正好体现的是
队列的用法,算法就不说了,网上很多介绍。自己动手写了个。
Code
using System;
public class Primering
{
private int[] ring;
private myQueue mq;
public Primering(int n)
{
ring=new int[n];
mq=new myQueue(20);
initPrime();
}
public void initPrime()
{
for(int i=2;i<=ring.Length;i++)
{
mq.EnQueue(i);
//Console.Write(mq.DeQueue());
}
}
public bool IsPrime(int pm)
{
if(pm==2)
return true;
if(pm<3 || pm%2==0)
return false;
int j=(int)Math.Sqrt(pm);
bool yes=true;
if(j%2==0)
j--;
while(j>2 && yes)
if(pm%j==0)
yes=false;
else
j-=2;
if(yes)
return true;
else
return false;
}
public bool isPrime(int k)
{
int j=2;
if(k==2)
return true;
if(k<2 || k>2 && k%2==0)
return false;
else
{
j=3;
while(j<k && k%j!=2)
j=j+2;
if(j>=k)
return true;
else
return false;
}
}
public void primering()
{
int i=0,j,k;
ring[0]=1;
while(!mq.IsEmpty())
{
k=(int)mq.DeQueue();
// Console.Write(k+" ");
j=ring[i]+k;
if(IsPrime(j))
{
i++;
ring[i]=k;
}
else
mq.EnQueue(k);
}
}
public void test()
{
int i=0,j,k;
ring[0]=1;
while(!mq.IsEmpty())
{
mq.EnQueue(1);
Console.Write(mq.DeQueue()+" ");
Console.Write(mq.DeQueue()+" ");
Console.WriteLine();
/*
k=(int)mq.DeQueue();
if(isPrime(k))
Console.Write(k+" ");
else
{
k=k+1;
mq.EnQueue(k);
}
*/
}
}
public void output()
{
for(int i=0;i<ring.Length;i++)
{
Console.Write(ring[i]+" ");
}
}
public static void Main()
{
Primering pri=new Primering(10);
// for(int i=0;i<=20;i++)
// if(pri.IsPrime(i))
// Console.Write(i+" ");
pri.primering();
// pri.test();
pri.output();
}
}
还是没有注释,以后忘记的再补上。
栈和队列就复习完了,但是有两个我非常关注的习题却没有时间做,一个是走迷宫,还一个是骑士游历。因为开学了事情非常多,
我想只能利用学习之余继续复习数据结构了。