使用不带头结点的循环链表实现队列(数据结构)

Posted zhchoutai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用不带头结点的循环链表实现队列(数据结构)相关的知识,希望对你有一定的参考价值。

我使用类模版来完毕循环链表实现队列的操作。首先定义一个结点类node用来保存结点信息,然后定义队列类Queue。接下来我们思考:要完毕队列的4个基本操作即
1.推断队列是否为空
2.在队列尾部push进数据
3.从队列头部取出数据
4.删除掉队列首部的元素
我们这个Queue类须要什么成员变量?
答案是: (维护)队列尾部结点、队列大小就够了。

我们来分析。尾部push数据的时候,我们仅仅须要在myback和myback->next之间插入这个结点。然后把这个myback指向这个结点就可以。取出和删除头部数据仅仅须要对myback->next进行操作就可以,复杂度是O(1),效率非常高。

技术分享

剩下的一些实现细节看我以下的代码实现:

//circle_list.h
#ifndef CIRCLE_LIST
#define CIRCLE_LIST
#include<iostream>
#include<string>
#include<cstring>
template <typename T>
class node//节点类
{
public:
	T data;
	node *next;
	node(T da = 0, node *n = NULL) :data(da), next(n){}
};
template <typename T>
class Queue
{
public:
	node<T> *myback;
	int size;
	Queue(node<T> *begin = NULL, int s = 0) :myback(begin),size(s){}
	bool empty();
	void enqueue(T value);//后面压入
	T front();
	void display();
	void dequeue();//前面删除
	~Queue();
	Queue(const Queue<T> &temp);
	Queue<T> operator=(const Queue<T>temp);
};
template <typename T>
bool Queue<T>::empty()
{
	if (size == 0)
		return true;
	return false;
}
template <typename T>
Queue<T>::Queue(const Queue<T> &temp)
{
		size = 0;
		node<T>* scan = (temp.myback)->next;
		while (scan != temp.myback)
		{
			enqueue(scan->data);
			scan = scan->next;
		}
		enqueue(temp.myback->data);

}
template <typename T>
Queue<T> Queue<T>::operator=(const Queue<T> temp)
{

		size = 0;
		node<T>* scan = (temp.myback)->next;
		while (scan != temp.myback)
		{
			enqueue(scan->data);
			scan = scan->next;
		}
		enqueue(temp.myback->data);
	return *this;
}


template <typename T>
void Queue<T>::enqueue(T value)
{

	node<T>*last = new node<T>;
	last->data = value;
	if (size == 0)
	{
		myback = last;
		myback->next = myback;
	}
	else
	{
		node<T> *temp = myback->next;
		myback->next = last;
		last->next = temp;
		myback = last;
		myback->next = temp;
	}
	size++;
}
template <typename T>
T Queue<T>::front()
{
	return (myback->next)->data;
}
template <typename T>
void Queue<T>::display()
{
	if (size == 1)
	{
		cout << myback->data << endl;
		return;
	}
	else
	{
		node<T> *first = myback->next;
		while (first != myback)
		{
			cout << first->data << " ";
			first = first->next;
		}
		cout << myback->data;
		cout << endl;
	}
}
template <typename T>
void Queue<T>::dequeue()
{

	node<T>*cur = myback->next;
	node <T>*now = cur->next;
	myback->next = now;
	delete cur;
	size--;
}
template <typename T>
Queue<T>::~Queue()
{
	if (size == 0){}
	else
	{
		node<T> *p = myback->next;
		node<T> *nex = p->next;
		while (p != myback)
		{
			delete p;
			p = nex;
			nex = nex->next;
		}
		delete myback;
	}
}

#endif

进行測试:

//main.cpp
#include"circle_list.h"
using namespace std;
int main()
{
	Queue<int> q;
	cout <<"队列是否为空?"<< q.empty() << endl;
	q.enqueue(1);
	q.enqueue(2);
	q.enqueue(3);
	cout << "输出第一个队列中的数据:" << endl;
	q.display();
	Queue<int> a(q);
	cout << "输出通过拷贝构造函数建立的队列中的数据:" << endl;
	a.display();
	Queue<int> b;
	b = q; cout << "输出通过赋值运算符重载建立的队列中的数据:" << endl;
	b.display();
	cout << "输出队列首的元素:" << endl;
	cout << q.front() << endl;
	q.dequeue();
	cout << "删除队首元素后的队列:" << endl;
	q.display();
	//cout << q.empty() << endl;
	return 0;
}

实验结果截图;

技术分享











以上是关于使用不带头结点的循环链表实现队列(数据结构)的主要内容,如果未能解决你的问题,请参考以下文章

带头结点的循环链表实现约瑟夫环

[PTA][C语言][数据结构]队列的操作集合(带尾指针的循环链表)

循环链表的建立及各种操作

C语言实现双向非循环链表(带头结点尾结点)的节点插入

java实现单向循环链表

数据结构Java实现04----循环链表仿真链表