2021-12-22 数据结构—线性表—队列 (c++与c语言代码)

注意:取余符号 % 的意思

% 除数小于被除数,结果就是除数
除数大于等于被除数,结果就是余数

1. 什么是队列

队列(Queue):具有一定操作约束的线性表
队头与队尾: 允许元素插入的一端称为队尾,允许元素删除的一端称为队头。
插入和删除操作:只能在一端(front)插入,而在另一端(rear)删除
数据插入:入队列(AddQ)
数据删除:出队列(DeleteQ)
先进先出:FIFO
特点:1.队列中的数据元素遵循“先进先出”(First In First Out)的原则,简称FIFO结构。
2.在队尾添加元素,在队头删除元素。

2. 队列的顺序存储结构实现(★★★★★★★有图★★★★★★★)

在这里插入图片描述
在这里插入图片描述

2.1 模板

C++
begin:队首标志 end:队尾标志 capacity:数组容量 queue:数组

template <typename T>
class LoopQueue
{
public:
    LoopQueue(int c = 10);
    ~LoopQueue();
public:
    bool isEmpty();        //队列的判空
    int size();            //队列的大小
    bool push(T t);        //入队列
    bool pop();            //出队列
    T front();            //队首元素
 
private:
    int capacity;
    int begin;
    int end;
    T*  queue;
};

C
类型名称:队列(Queue)
数据对象集:一个有 0 个或多个元素的有穷线性表
操作集:长度为 MaxSize 的队列 Q∈Queue,队列元素 item∈ElementType
队列的基本操作主要有:

#include<stdio.h>
#include<malloc.h>
#define MaxSize 100
typedef int ElementType;
typedef struct QNode *Queue;
struct QNode{
	ElementType Data[MaxSize];
	int front;   // 记录队头 
	int rear;    // 记录队尾 
};

Queue CreateQueue(int MaxSize):生成长度为 MaxSize 的空队列
int IsFull(Queue Q):判断队列 Q 是已满
void AddQ(Queue Q,ElementType item):将数据元素 item 插入队列 Q 中
int IsEmpty(Queue Q):判断队列 Q 是否为空
ElementType DeleteQ(Queue Q):将队头数据元素从队列中删除并返回

2.2 初始化构造

C++

template<typename T>
LoopQueue<T>::LoopQueue(int c = 10)
:
{
	capacity = c;
	begin = 0;
	end = 0;
    queue = new T[capacity];
    queue(nullptr)
};

C

// 初始化 
Queue CreateQueue(){
	Queue Q;
	Q = (Queue)malloc(sizeof(struct QNode));
	Q->front = -1;
	Q->rear = -1;
	return Q;
} 

2.3 析构函数

C++

template<typename T>
LoopQueue<T>::~LoopQueue()
{
    delete[]queue;
}

2.4 判断是否为空

C++

template <typename T>
bool LoopQueue<T>::isEmpty()
{
    if (begin == end)
        return true;
    return false;
};

C

//判断队列是否为空
int IsEmpty(Queue Q){
	return (Q->front == Q->rear);
}

2.5 判断队列是否已满

C++

template <typename T>
bool LoopQueue<T>::pop()
{
    if (end == begin) //判断队列是否为空
    {
        return false;
    }
    begin = (begin + 1) % capacity;
    return true;
};

C

// 判断队列是否已满
int IsFull(Queue Q){
 	return ((Q->rear+1) % MaxSize == Q->front);
}

2.6 入队

在这里插入图片描述
添加元素时,元素只能从队尾一端进入队列,也即是2只能跟在1后面,3只能跟在2后面。
C++

template<typename T>
bool LoopQueue<T>::push(T t)
{
    if (end + 1 % capacity == begin) //判断队列是否已满  end + 1 % capacity == begin ,end + 1 % capacity余数是否为零?
    {
        return false;
    }
    queue[end] = t;
    end = (end + 1) % capacity;
    return true;
};

C

// 入队 
void AddQ(Queue Q,ElementType item){
	if(IsFull(Q)){
		printf("队列满");
		return;
	}else{ 
		Q->rear = (Q->rear+1) % MaxSize;  //(Q->rear+1) % MaxSize =Q->rear+1 ,只要小于MaxSize ,那么结果还是rear+1 !!!!!!
		Q->Data[Q->rear] = item; 
	}
}

2.7 出队

在这里插入图片描述
元素只能从队首出队列,出队列的顺序为:1、2、3,与入队时的顺序一致,这就是所谓的“先进先出”。
C++

template <typename T>
bool LoopQueue<T>::pop()
{
    if (end == begin) //判断队列是否为空
    {
        return false;
    }
    begin = (begin + 1) % capacity;
    return true;
};

C

// 出队
ElementType DeleteQ(Queue Q){
	if(IsEmpty(Q)){
		printf("队列空");
		return 0;
	}else{
		Q->front = (Q->front+1) % MaxSize;
		return Q->Data[Q->front];
	}
} 

2.8 测试

C

int main(){
	Queue Q;
	Q = CreateQueue();
	AddQ(Q,3);
	printf("3入队\n");
	AddQ(Q,5);
	printf("5入队\n");
	AddQ(Q,11);
	printf("11入队\n");
	printf("%d出队\n",DeleteQ(Q));
	printf("%d出队\n",DeleteQ(Q));
	return 0;
} 

C++

int main()
{
    LoopQueue<string> queue(6);
    queue.push("one");
    queue.push("two");
    queue.push("three");
    queue.push("four");
    queue.push("five");
    cout << "队列长度" << queue.size() << endl;
    while (!queue.isEmpty())
    {
        cout << queue.front() << endl;
        queue.pop();
    }
    getchar();
    return 0;
}

3. 队列的链式存储结构实现

在这里插入图片描述

在这里插入图片描述

队列为空的时候,front和rear指针都指向头结点

在这里插入图片描述
在这里插入图片描述
队列的链式存储结构也可以用一个单链表实现。插入和删除操作分别在链表的两头进行,front 在链表头,rear 在链表尾,从 rear 入队,从 front 出队
在这里插入图片描述
队列的链式存储结构也可以用一个单链表实现。插入和删除操作分别在链表的两头进行,front 在链表头,rear 在链表尾,从 rear 入队,从 front 出队
在这里插入图片描述

3.1 模板

C++

template<typename T>
struct Node
{
    Node(T t) :value(t), next(nullptr){}
    Node() = default;
 
    T value; //vaule : 链表节点的值
    Node<T> * next;  //next : 指针,指向下一个节点
}

template<typename T>
class LinkQueue
{
public:
    LinkQueue();
    ~LinkQueue();
 
    bool isEmpty();
    int size();
    bool pop();
    void push(T t);
    T front();
 
private:
    Node<T>* phead;
    Node<T>* pend;
    int count;
};

C

#include<stdio.h>
#include<malloc.h>
typedef int ElementType;
typedef struct QNode *Queue;
struct Node{
	ElementType Data;
	struct Node *Next;
};
struct QNode{
	struct Node *rear;    // 指向队尾结点 
	struct Node *front;   // 指向队头结点 ?????????????????????????????????????????????????
};

Queue CreateQueue();  // 初始化队列 
void AddQ(Queue Q,ElementType item);  //  入队
ElementType DeleteQ(Queue Q);  // 出队 
int IsEmpty(Queue Q); // 判断队列是否为空 

3.2 初始化构造

C++

template<typename T>
LinkQueue<T>::LinkQueue()
    :phead(nullptr),pend(nullptr),count(0)
{
    phead = new Node<T>();
    pend = phead;
    count = 0;
};

C

// 初始化 
Queue CreateQueue(){
	Queue Q;
	Q = (Queue)malloc(sizeof(struct QNode));
	Q->front = NULL;
	Q->rear = NULL;
	return Q;
}

3.3 析构函数

template <typename T>
LinkQueue<T>::~LinkQueue()
{
    while (phead->next != nullptr)
    {
        Node<T> * pnode = phead;
        phead = phead->next;
    }
};

3.4 判断是否为空

C++

template <typename T>
bool LinkQueue<T>:: isEmpty()
{
    return count==0;
};

C

// 是否为空 
int IsEmpty(Queue Q){
	return (Q->front == NULL && Q->rear== NULL);
}

3.5 队列大小

C++

template <typename T>
int LinkQueue<T>::size()
{
    return count;
};

3.6 入队 (队列为空的时候,front=rear=NULL)

C++

//在队尾插入
template <typename T>
void LinkQueue<T>::push(T t)
{
    Node<T>* pnode = new Node<T>(t);  //创建一个结点
    pend->next = pnode; //将原来的尾指针指向它
    pend = pnode; //将它更新成尾结点
    count++; //计数器加一
};

C
在这里插入图片描述

// 入队
void AddQ(Queue Q,ElementType item){
	struct Node *node;
	node = (struct Node *)malloc(sizeof(struct Node));
	node->Data = item;
	node->Next = NULL;
	if(Q->rear==NULL){  //此时队列空 
		Q->rear = node;
		Q->front->next = node;
	}else{ //不为空 
		Q->rear->Next = node;  // 将结点入队 
		Q->rear = node;   // rear 仍然保持最后 
	}
} 

3.7 出队

C++

//在队首弹出
template <typename T>
bool LinkQueue<T>::pop()
{
    if (count == 0)
        return false;
    Node<T>* pnode = phead->next;
    phead->next = phead->next->next;  //将第二个结点变成第一个,原来第一个删除掉
    delete pnode;
    count--;
    return true;
};

C
在这里插入图片描述

// 出队
ElementType DeleteQ(Queue Q){
	struct Node *FrontCell;
	ElementType FrontElem;
	if(IsEmpty(Q)){
		printf("队列空");
		return 0;
	}//_______________________________________已经修改_________________________________
	FrontCell = Q->front->next;  //找到第一个元素结点  ???????????????????????????????????????
	if(Q->front->next == Q->rear){ // 队列中只有一个元素 ,因为已经排除队列为空的情况了
		Q->front = Q->rear = NULL; 
	}else{
		Q->front->next = Q->front->Next->next;
	}
	FrontElem = FrontCell->Data;
	free(FrontCell);
	return FrontElem;
}

3.8 测试

C++

int _tmain(int argc, _TCHAR* argv[])
{
    LinkQueue<string> lqueue;
    lqueue.push("one");
    lqueue.push("two");
    lqueue.push("three");
    lqueue.push("four");
    lqueue.push("five");
    cout << "队列的大小" << lqueue.size() << endl;
    while (!lqueue.isEmpty())
    {
        cout << lqueue.front() << endl;
        lqueue.pop();
    }
    getchar();
    return 0;
}

C

int main(){
	Queue Q;
	Q = CreateQueue();
	printf("入队5\n"); 
	AddQ(Q,5);
	printf("入队4\n"); 
	AddQ(Q,4);
	printf("入队4\n"); 
	AddQ(Q,3);
	printf("出队%d\n",DeleteQ(Q));
	printf("出队%d\n",DeleteQ(Q));
	printf("出队%d\n",DeleteQ(Q));
	printf("%d\n",DeleteQ(Q));
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值