数据结构与算法——队列

一、队列的定义

这里我用一个生活中的小例子引出队列的定义和一些特点

队列在现实生活中有很多的例子,就比如食堂排队的时候,就是一个典型的队列,而作为排队的人就是队列中的元素,先到食堂窗口的率先买上饭就可以离开了,但是也有一些意外的情况,就比如有一些同学喜欢乱插队,导致后面的同学要多等一个人,也有时呢,前面的某个同学不想吃这家窗口的饭了,然后离开了,在他之后的学生呢,也都会向前一步,还有当饭卖完了,这个窗口排队的人就唉声叹气解散了。

根据例子不难可以发现,队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

队列的种类

      1.顺序表建立的队列

      2.链表建立的队列

      3.循环队列

二、队列的特点:

        1.仅在表尾进行插入操作,表头进行删除操作的线性表

        2.先进先出(FIFO -- First int first out)!

        3.插入--> 入队  删除-->出队

三、队列的基本操作

同样跟前面线性表一样,队列呢也有顺序结构和链式结构,在项目或者实例中呢往往用的循环顺序队列比较多。

        1.队列结构定义

        

#define MAXSIZE 100

struct Queue
{
    QElemtype *base;  //QElemtype 为自定义的数据类型
    int front;        //用int类型指向队列的头位置
    int rear;         //指向队列的尾位置
};

注意: 关于队列的溢出问题

1.解决假上溢的方法:

将空间想成一个循环的表,即分配给队列的存储单元可以循环使用,当rear = maxsize,若向量的开端空着,又可以从头使用,当front为maxsize时也同样使用。

引入循环队列

base[0]按在base[maxsize - 1] 之后,若rear+1==M,则令rear=0。利用模(mod,c语言中:%)运算。

添加元素:

Q.base[Q.rear] = x;

Q.rear[Q.rear + 1] % MAXSIZE

删除元素:

x = Q.base[Q.front]

Q.front = (Q.front + 1)%MAXSIZE

        2.初始化


//顺序表
void Init()
{
    base = new QElemtype[MAXSIZE];
    rear = front = 0;
}

//链式
void Init()
{
    front = rear = new Qnode[MAXSIZE];
    if(!front)
        cout <<"初始化失败";exit(0);
    front->next = nullptr;
}

 

 

         3.销毁队列

void release()
{
	delete []base;
}

        4.入队列

        

void Enqueue(QElemtype e)
{
    if(IsFull())
        cout <<"queue have been fulled"<<endl;
    this->base[rear] = e;
    rear = (rear+1)%MAXSIZE;
}

        5.出队列

  

void Dequeue(QElemtype &e)
{
	if(IsEmpty())
		cout <<"the queue haven't data"<<endl;
	e = base[front];
	front = (front+1)%MAXSIZE;
}

还有一些比较简单的操作,例如判断队列是否为空,是否为满,获取队列头元素。这些方法我写到总汇里面(第四部分)里面去了。 

四、代码整合        

在实例中用C++类模板的方法整合所有代码,可以调用类直接使用类的接口函数。

1

、顺序结构

#ifndef QUEUE_H_
#define QUEUE_H_
#define MAXSIZE 5
#include<cstdlib>
#include<iostream>
using std::cout;
using std::endl;

template<class T>
class Queue
{
	private:
		T* base;
		int front;
		int rear;
	public:
		Queue();
		~Queue();
		bool IsEmpty();
		bool IsFull();
		void Enqueue(T e);
		void Dequeue(T &e);
		T GetHead();
};

template<class T>
Queue<T>::Queue()
{
	this->base = new T[MAXSIZE];
	front = rear = 0;
}

template<class T>
Queue<T>::~Queue()
{
	delete []base;
}

template<class T>
bool Queue<T>::IsEmpty()
{
	if(rear == front)
		return true;
	else
		return false;
}

template<class T>
bool Queue<T>::IsFull()
{
	if((rear+1)%MAXSIZE == front)
		return true;
	else
		return false;
}

template<class T>
void Queue<T>::Enqueue(T e)
{
	if(IsFull())
		cout << "queue have been fulled"<<endl;
	this->base[rear] = e;
	rear = (rear+1)%MAXSIZE;
}

template<class T>
void Queue<T>::Dequeue(T &e)
{
	if(IsEmpty())
		cout <<"the queue haven't data"<<endl;
	e = base[front];
	front = (front+1)%MAXSIZE;
}
template<class T>
T Queue<T>::GetHead()
{
	if(front != rear)
		return base[front];
}

#endif

二、链式结构

#ifndef QUEUE_H_
#define QUEUE_H_
#define MAXSIZE 100
#include<cstdlib>
typedef int Elemtype;

struct Qnode
{
	Elemtype data;
	struct Qnode* next;
};

typedef struct Qnode* LinkQueue;
template<class T>
class Queue
{
	private:
		LinkQueue front;
		LinkQueue rear;
	public:
		Queue();
		~Queue();	
		void Enqueue(T e);
		void Dequeue(T &e);
		void GetHead(T &e);

};

template<class T>
Queue<T>::Queue()
{
	front = rear = new Qnode[MAXSIZE];
	if(!front)
		exit(0);
	front->next = nullptr;
}

template<class T>
Queue<T>::~Queue()
{
	while(front)
	{
		LinkQueue p = front->next;
		delete front;
		front  = p;
	}
}

template<class T>
void Queue<T>::Enqueue(T e)
{
	LinkQueue p = new Qnode[MAXSIZE];
	if(!p)
		exit(0);
	p->data = e;
	p->next = nullptr;
	rear->next = p;
	rear = p;
}

template<class T>
void Queue<T>::Dequeue(T &e)
{
	if(front == rear)
		exit(0);
	LinkQueue p = front->next;
	e = p->data;
	front->next = p->next;
	delete p;
}
template<class T>
void Queue<T>::GetHead(T &e)
{
	e = front->next->data;
}
#endif

 五、总结

队列这部分更新完了,纯手敲,后面继续写其他的数据结构。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值