c# 回调先进先出_【数据结构】【C#】008-队列:顺序队列(循环队列)

C#数据结构:顺序队列

1、 顺序队列的假溢出现象

队列的一种顺序存储称为顺序队列。与顺序栈类似,在队列的顺序存储结构中,用一组地址连续的存储单元依次存放从队头到队尾的元素,如一维数组 Queue[MAXSIZE]。

由于队列中队头和队尾的位置都是动态变化的,因此需要附设两个指针 front 和 rear。

front:指示队头元素在数组中的位置;

rear:指示真实队尾元素相邻的下一个位置。

初始化队列时,令 front = rear =0;

入队时,直接将新元素送入尾指针 rear 所指的单元,然后尾指针增 1;出队时,直接取出队头指针 front 所指的元素,然后头指针增 1。显然,在非空顺序队列中,队头指针始终指向当前的队头元素,而队尾指针始终指向真正队尾元素后面的单元。当 rear==MAXSIZE 时,认为队满。但此时不一定是真的队满,因为随着部分元素的出队,数组前面会出现一些空单元,如下图(d)所示。由于只能在队尾入队,使得上述空单元无法使用。把这种现象称为假溢出,真正队满的条件是 rear - front=MAXSIZE 。

img.jpg

2、 循环队列

为了解决假溢出现象并使得队列空间得到充分利用,一个较巧妙的办法是将顺序队列的数组看成一个环状的空间,即规定最后一个单元的后继为第一个单元,我们形象地称之为循环队列。

假设队列数组为 Queue[MAXSIZE],当 rear+1=MAXSIZE 时,令rear=0,即可求得最后一个单元 Queue[MAXSIZE-1]的后继:Queue[0]。更简便的办法是通过数学中的取模(求余)运算来实现:

ear=(rear+1)mod MAXSIZE,显然,当 rear+1=MAXSIZE 时,rear=0,

同样可求得最后一个单元 Queue[MAXSIZE-1]的后继:Queue[0]。所以,借助于取模(求余)运算,可以自动实现队尾指针、队头指针的循环变化。

进队操作时,队尾指针的变化是:rear=(rear+1)mod MAXSIZE ;

而出队操作时,队头指针的变化是:front=(front+1)mod MAXSIZE。

3、顺序队列的实现:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

///

/// 顺序队列

///

///

public class SeqQueue

{

private T[] data;

private int front;//队首

private int rear;//队尾

private int count;//队中个数

//初始化

public SeqQueue(int size)//size:最大容量

{

data = new T[size];

front = 0;

rear = 0;

count = 0;

}

public SeqQueue() : this(10)

{

}

//最大容量

public int MaxSize

{

get

{

return data.Length;

}

}

//队中元素个数

public int Count

{

get

{

return count;

}

set

{

count = value;

}

}

//判空

public bool IsEmpty()

{

return Count == 0;

}

//判满

public bool IsFull()

{

return Count == MaxSize;

}

//入队

public void Enqueue(T item)

{

if (IsFull())

{

throw new System.Exception("队满,无法入队!");

}

data[rear] = item;

Count++;

rear = (rear + 1) % MaxSize;//修改队尾指针

}

//出队

public T Dequeue()

{

if (IsEmpty())

{

throw new System.Exception("队空,无法出队!");

}

T t = data[front];

front = (front + 1) % MaxSize; //修改队首指针

Count--;

return t;

}

//访问队首元素

public T Peek()

{

if (IsEmpty())

{

throw new System.Exception("队空,无法访问队首!");

}

return data[front];

}

//清空队列

public void Clear()

{

front = 0;

rear = 0;

Count = 0;

}

}

顺序队列:测试用例

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class _008_SeqQueue : MonoBehaviour

{

SeqQueue seqQueue;

void Start()

{

//初始化队列

seqQueue = new SeqQueue(4);//size=4

//队列最大容量

Debug.Log("队列最大容量:" + seqQueue.MaxSize);

//判空

Debug.Log("队列是否空:" + seqQueue.IsEmpty());

//判满

Debug.Log("队列是否满:" + seqQueue.IsFull());

//入队列

Debug.Log("入队列:" + "1,2,3,4");

seqQueue.Enqueue("1");

seqQueue.Enqueue("2");

seqQueue.Enqueue("3");

seqQueue.Enqueue("4");

//队列中元素个数

Debug.Log("队列中元素个数: " + seqQueue.Count);

//判满

Debug.Log("队列是否满:" + seqQueue.IsFull());

//出队列

Debug.Log("出队列-----出队列值为:" + seqQueue.Dequeue());

//队列中元素个数

Debug.Log("出队列后,队列中元素个数: " + seqQueue.Count);

//访问队首元素

Debug.Log("队首元素值: " + seqQueue.Peek());

//队列中元素个数

Debug.Log("访问队首后,队列中元素个数: " + seqQueue.Count);

//清空队列

seqQueue.Clear();

Debug.Log("清空队列!");

//队列中元素个数

Debug.Log("清空队列后,队列中元素个数: " + seqQueue.Count);

}

}

输出结果:

img.jpg

注:

1、 队列的定义与特点

队列 (Queue) 是另一种限定性的线性表,它只允许在表的一端插入元素,而在另

一端删除元素。队列具有先进先出 (Fist In Fist Out,缩写为 FIFO)的特性。

2、 队列的基本操作

进队(插入)、出队(删除)。

3、 队列的存储:链队列、循环队列

4、 循环队列:将顺序队列数组视为首尾相接的队列,模运算支持克服假溢出。

区分循环队列队空队满的两种方法:

损失一个元素空间;

增设标志量 count。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值