zoukankan      html  css  js  c++  java
  • 数据结构-环形队列-队列模板实现-c++代码

    一、队列(FIFO-first in first out)

    • 分类:
      • 普通队列: 先进先出,读取时有两种:一种是指针移动向下读取;一种是每读取一个元素,后面的所有元素自动向前移动一个位置。
        • 这两种办法都有缺点。第一种会造成出栈后的数据的位置没有被重新利用,内存浪费。第二种是每次读出一个元素,后面所有元素都前进移动,效率低下。
      • 环形队列: 预先设定环形队列可容纳值的大小,分头指针和尾指针指示队列的头和尾。存储时存在尾指针位置,然后尾指针加一。读取时读头指针位置,头指针加一。这样所有的空间可以循环利用。利用判空或判满函数来决定队列是否还有元素或者队列是否已满。
        • 缺点是队列大小不可变,如果队列满了,就不能再加入新元素。但是效率高,空间利用同样高效。
    • Note that:
      • 新建类对象在创建该类型的数组时,为防止报错,需要给构造函数里的元素赋初值

    环形队列实现代码

    //队列模板实现.h文件
    #pragma once
    #include<iostream>
    using namespace std;
    template<class T>
    class Myqueue
    {
    public:
    	Myqueue(int num);//构建队列大小
    	void addIngre(T m);//增加元素
    	void deleIngre();//删除元素
    	int IngreNum();//返回当前队列元素个数
    	bool queueFull();//判断满
    	void clearIngre();//清空队列
    	bool queueEmpty();//判空队列
    	void queueTraverse();//遍历元素
    	~Myqueue();//析构
    
    private:
    	int m_iNum;	//队列元素个数
    	T* m_tArray;//数组
    	int m_iHead;//头指针位置
    	int m_iTail;//尾指针位置
    	int m_iSize;//队列大小
    
    };
    template<class T>
    Myqueue<T>::Myqueue(int num)
    {
    	clearIngre();
    	m_iSize = num;
    	m_tArray = new T[m_iSize];
    }
    template<class T>
    Myqueue<T>::~Myqueue()
    {
    	delete[]m_tArray;
    	m_tArray = NULL;
    }
    template<class T>
    void Myqueue<T>::addIngre(T m)//增加元素
    {
    	if (!queueFull())
    	{
    		m_iNum++;
    		m_iTail = m_iTail % m_iSize;
    		m_tArray[m_iTail] = m;
    		m_iTail++;
    	}
    	else
    	{
    		cout << "Can not add any more ingredients!" << endl;
    	}
    }
    
    template<class T>
    void Myqueue<T>::deleIngre()//首元素出队
    {
    	if (!queueEmpty())
    	{
    		m_iNum--;
    		cout <<"被消除的首元素为:"<< m_tArray[m_iHead] << endl;
    		m_iHead++;
    		m_iHead = m_iHead % m_iSize;
    	}
    	else
    	{
    		cout << "There is no ingredient!" << endl;
    	}
    
    }
    
    template<class T>
    int Myqueue<T>::IngreNum()//返回当前队列元素个数
    {
    	cout << "当前元素个数为:" <<m_iNum<< endl;
    	return m_iNum;
    }
    
    template<class T>
    void Myqueue<T>::clearIngre()
    {
    	m_iNum = 0;
    	m_iTail = m_iHead = 0;
    	cout << "当前元素个数为:" << m_iNum << endl;
    }//清空队列
    
    template<class T>
    bool Myqueue<T>::queueEmpty()
    {
    	return m_iNum == 0 ? true : false;
    }//判空队列
    template<class T>
    bool Myqueue<T>::queueFull()
    {
    	return m_iNum == m_iSize ? true : false;
    }//判断满
    template<class T>
    void Myqueue<T>::queueTraverse()
    {
    	for (int i = m_iHead; i < m_iNum + m_iHead; i++)
    	{
    		i = i % m_iSize;
    		cout << m_tArray[i] << endl;
    	}
    }//遍历元素
    
    
    //自定义类customer的.h文件
     #pragma once
    #include<iostream>
    using namespace std;
    #include<string>
    
    class customer
    {
    	friend ostream& operator<<(ostream& out, customer& c)//<<重载只能用友元函数,因为与this指针无关
    	{
    		out << "Name:"<<c.name<<","<<"Age:" << c.age;
    		return out;//必须有返回值
    	}
    public:
    	customer(string n="陈胖鹿",int a=4);//为了防止自定义类在创建数组时报错,需要赋初值。猜测是因为编译器没有初值的话不知道需要开辟多少内存出来。
    	~customer();
    	//重载<<
    	//重载=
    	customer& operator=(customer& m)
    	{
    		this->name = m.name;
    		this->age = m.age;
    		return *this;//必须返回
    	}
    
    private:
    	string name;
    	int age;
    };
    //自定义类的.cpp文件
    #include"customer.h"
    
    customer::customer(string n, int a):name(n),age(a)
    {
    }
    
    customer::~customer()
    {
    }
    
    //main.cpp;Note that: 队列的模板<>内可以是任何编译器已经存在的类型如int,double,float,string等。如果想加入自定义的类,则自定义类需要重"=","<<"两个符号,本例中自定义类已经重载该两个符号
    #include"Myqueue.h"
    #include<string>
    #include"customer.h"
    int main()
    {
    	Myqueue<customer> * p = new Myqueue<customer>(4);
    	customer c1("张三",43);
    	customer c2("张四", 44);
    	customer c3("张五", 46);
    	p->addIngre(c1);
    	p->addIngre(c2);
    	p->addIngre(c3);
    	p->queueTraverse();
    	cout << endl;
    	p->deleIngre();
    	p->deleIngre();
    	p->deleIngre();
    	p->IngreNum();
    
    	delete p;//需要删除p
    	p = NULL;//并将其置于安全状态
    
    	return 0;
    }
    
    Higher you climb, more view you will see.
  • 相关阅读:
    关于delphi xe8安装完之后的关键步骤
    delphi xe8开发安卓程序:访问服务器上的配置文件
    delphi grideh使用
    delphi 获取可执行文件的当前路径
    Delphi XE10下用FireDAC与SQLite连接要注意的问题
    Google Map Api 自定义maker样式和InfoWindow样式(叠加层)
    地理定位(navigator.geolocation)
    document.documentElement和document.body的区别
    【JavaScript】Function类型
    Ubuntu 14.04 安装 php5.6
  • 原文地址:https://www.cnblogs.com/yyfighting/p/12500620.html
Copyright © 2011-2022 走看看