[数据结构]队列之链式队列的类模板实现

链式队列是基于单链表的一种存储表示

队列的对头指针指向单链表的第一个节点,队尾指针指向单链表的最后一个节点,

退出一个元素 则删除对头指针的节点,添加元素则在队尾增加一个节点

使用条件:数据元素变动比较大的情况。不存在溢出的情况

队列的抽象基类:

#ifndef QUEUE
#define QUEUE
//队列的抽象基类

template<class T>
class Queue
{
public:
    Queue(){}
    ~Queue(){}
    virtual bool EnQueue(const T& x)=0;
    virtual bool DeQueue(T& x)=0;
    virtual bool getFront(T& x)const=0;
    virtual bool IsEmpty()const=0;
    virtual bool IsFull()const=0;
    virtual int getSize()const=0;
};

#endif

链式队列的具体实现:

/////////////////////////
#include"Stack.h"
#include <iostream>
//#include <cstdlib>
#include <cassert>
using namespace std;

template<class T>
struct LinkNode //链表节点类
{
    T data;
    LinkNode<T>* link;  

    LinkNode(LinkNode<T>* ptr=NULL):link(ptr){}
    LinkNode(const T& item,LinkNode<T>* ptr=NULL):data(item),link(ptr){}
}; 

template<class T>
class LinkedQueue:public Queue<T>
{
public:
    LinkedQueue():front(NULL),rear(NULL){}
    ~LinkedQueue(){makeEmpty();}
    LinkedQueue(const LinkedQueue<T>& rhs);
    LinkedQueue<T>& operator=(const LinkedQueue<T>& rhs);

    bool EnQueue(const T& x);
    bool DeQueue(T& x);
    bool getFront(T& x)const;
    bool IsEmpty()const{return (front==NULL)?true:false;}
    bool IsFull()const{return false;}//无意义,永远不可能满
    int getSize()const;

    void makeEmpty();
    friend ostream& operator<< <T>(ostream& os,const LinkedQueue<T>& rhs);

protected:
    LinkNode<T> *front,*rear;
};

template<class T>
void LinkedQueue<T>::makeEmpty()
{
    LinkNode<T>* p;
    while(front!=NULL){
        p=front;
        front=front->link;
        delete p;
    }
    rear=NULL;
}

template<class T>
bool LinkedQueue<T>::EnQueue(const T& x)
{
    if(front==NULL){
        front=rear=new LinkNode<T>(x);
        if(front==NULL||rear==NULL)//对new返回值的一个检测,安全机制
            return false;
    }
    else{
        rear->link=new LinkNode<T>(x);
        if(rear->link==NULL)
            return false;
        rear=rear->link;
    }
    return true;
}

template<class T>
bool LinkedQueue<T>::DeQueue(T& x)
{
    if(IsEmpty())
        return false;

    LinkNode<T>* p=front;
    if(front==rear){//只有一个节点的情况
        front=front->link;
        rear=NULL;
    }else{
        front=front->link;
    }
    x=p->data;
    delete p;
    return true;

}

template<class T>
bool LinkedQueue<T>::getFront(T& x)const
{
    if(IsEmpty())
        return false;
    x=front->data;
    return true;
}

template<class T>
int LinkedQueue<T>::getSize()const
{
    int k=0;
    LinkNode<T>* p=front;
    while(p!=NULL){
        ++k;
        p=p->link;
    }
    return k;
}

template<class T>
ostream& operator<<(ostream& os,const LinkedQueue<T>& rhs)
{
    os<<"size: "<<rhs.getSize()<<endl;
    LinkNode<T> *p=rhs.front;
    os<<"elements:";
    while(p!=NULL){
        os<<p->data<<" ";
        p=p->link;
    }
    os<<endl;
    return os;

}

template<class T>
LinkedQueue<T>::LinkedQueue(const LinkedQueue<T>& rhs)
{
    LinkNode<T> *src=rhs.front;
    LinkNode<T> *dest=nullptr,*newNode=nullptr;
    front=nullptr;
    while(src!=NULL){
        newNode=new LinkNode<T>(src->data);
        if(front==nullptr){    //链表为无附加头结点的单链表,故比较特殊
            front=newNode;
            dest=newNode;
        }else{
            dest->link=newNode;
            dest=newNode;
        }
        src=src->link;
    }
    rear=dest;
}

template<class T>
LinkedQueue<T>& LinkedQueue<T>::operator=(const LinkedQueue<T>& rhs)
{
    makeEmpty();

    LinkNode<T> *src=rhs.front;
    LinkNode<T> *dest=nullptr,*newNode=nullptr;
    front=nullptr;
    while(src!=nullptr){
        newNode=new LinkNode<T>(src->data);
        if(front==NULL){
            front=newNode;
            dest=newNode;
        }else{
            dest->link=newNode;
            dest=newNode;
        }
        src=src->link;
    }
    rear=dest;
    return *this;
}

测试函数:

int main(int argc, char* argv[])
{
    LinkedQueue<int> s;
    int a=1,b=2,c=3,d=4,e=0;
    s.EnQueue(a);
    s.EnQueue(b);
    s.EnQueue(c);
    s.EnQueue(d);
    cout<<s;
    s.DeQueue(e);
    s.DeQueue(e);
    cout<<s;

    cout<<"getSize(): "<<s.getSize()<<endl;

    cout<<boolalpha;
    cout<<"IsEmpty(): "<<s.IsEmpty()<<endl;
    cout<<"IsFull(): "<<s.IsFull()<<endl;
    cout<<noboolalpha;

    s.getFront(e);
    cout<<"getFront(): "<<e<<endl;

    cout<<endl;
    cout<<"copy and copy assignment"<<endl;
    LinkedQueue<int> s1(s),s2;
    cout<<s1;
    s2=s;
    cout<<s2;

    system("pause");
    return 0;
}

测试结果如下:

size: 4
elements:1 2 3 4
size: 2
elements:3 4
getSize(): 2
IsEmpty(): false
IsFull(): false
getFront(): 3

copy and copy assignment
size: 2
elements:3 4
size: 2
elements:3 4
请按任意键继续. . .

注意事项:

1.要对返回的指针值进行检测,比如用new时要对返回值进行检测,查看内存是否分配成功。这是随时随地的安全机制。

2.该实现所用的链表是没有附加头结点的单链表,所以拷贝构造函数和拷贝复制函数的编写要注意。

3.想清楚在写代码,否则漏洞很多。

时间: 2024-10-29 19:07:19

[数据结构]队列之链式队列的类模板实现的相关文章

[数据结构]栈之顺序栈的类模板实现

栈的数组实现形式,采用动态分配数组,不够时可以调整栈的大小. Stack.h文件:主要定义栈的抽象基类,提供公共的接口函数. #ifndef STACK #define STACK //栈的抽象基类 template<class T> class Stack { public: Stack(){} ~Stack(){} virtual void Push(const T& x)=0; virtual bool Pop(T& x)=0; virtual bool getTop(T

【数据结构】链式队列

//linkqueue.h #include "stdio.h" #include "stdlib.h" #include <string.h> #define MAXSZIE 30 struct qNode { char name[MAXSZIE]; char author[MAXSZIE]; int Pages; double Price; char IsForeign; struct qNode * next; }; typedef struct

队列——链式队列

原文地址:http://blog.csdn.net/hguisu/article/details/7674195 1 #include "stdafx.h" 2 #include "stdlib.h" 3 #include <stdio.h> 4 #include <iostream> 5 using namespace std; 6 7 #define TRUE 1 8 #define FALSE 0 9 #define OK 1 10 #

【数据结构-队列】链式队列

关于链式队列 链式队列又称为链队,是使用单链表实现的,需要一个头指针一个尾指针 结构图: 链队需要的元素组成 /*链式队列的每一个节点*/ struct node{ int data;//存储数据 struct node *next;//指向下一个节点的指针 }; /*链式队列*/ typedef struct{ struct node *head;//头指针 struct node *tail;//尾指针 }LinkedQueue; 创建一个带头节点的空队列 创建一个节点p 将p节点的next

链式队列总结

基本数据结构之-链式队列 链式队列就是一个操作受到限制的单链表,学会了单链表再来写这个就是轻松加愉快,但是貌似我去用了两个小时搞定,主要是基础差! 队列的基本操作就是入栈和出栈,还可以看到对头和对尾 如果维护了长度参数,那么也可以返回一个长度 不说理论了,直接上代码吧! 首先定义基本数据结构的结构体: typedef struct _LINKQUEUENODE { struct _LINKQUEUENODE *next; }LinkQueueNode; typedef struct _LINKQ

C++学习笔记36:类模板

类模板的目的 设计通用的类型式,以适应广泛的成员数据型式 类模板的定义格式 template<模板形式参数列表>class 类名称{...}; 原型:template<typename T> class A; 类模板的成员 像普通类的成员一样定义 定义在类中或类外均可,后者需要在类名后列些模板参数,以区别非模板类的成员函数 template<typename T> T A<T>::f(u) 类成员函数的模板 成员函数可以使用其他模板 template<

泛函编程—模板函数_类模板

函数业务逻辑一样,只是函数参数类型不同函数模板的本质:类型参数化——泛型编程 语法: template <typename T> template <class T1,class T2>多个参数类型 类型 函数名(形式参数表) { 语句序列: } 函数模板基础: template是告诉C++编译器,开始泛型编程,看到T,不要随便报错 template <typename T>//一个模板 void myswap(T& a, T& b) { T c; c

队列(循环队列)

队列 队列一般分为两类:链式队列和顺序队列 链式队列---链式队列即用链表实现的队列 顺序队列---顺序队列是用数组实现的队列,顺序队列通常必须是循环队列 1.基本概念: 队列是指允许在一端进行插入,在另一端进行删除的线性表,又称"先进先出"的线性表 队列是一种特殊的线性结构,它只允许在队列的首部(head)进行删除操作,这称为出队 队尾:允许插入的一端,用尾指针指向队尾元素的后一位置 排头:允许删除的一端,用头指针指向头元素 循环队列(顺序队列)的实现: 1 #include <

[数据结构]队列之顺序队列的类模板实现

队列是一种限定存取位置的线性表.同意插入的一端叫做队尾(rear),同意删除的一端叫做队首(front). 队列具有FIFO的性质 队列的存储表示也有两种方式:基于数组的,基于列表的.基于数组的叫做顺序队列.基于列表的叫做链式队列. 一下是基于动态数组的顺序队列的模板类的实现. 顺序队列的抽象基类例如以下所看到的:仅仅提供了接口和显式的默认构造函数和析构函数,在派生类中调用. #ifndef QUEUE #define QUEUE //队列的抽象基类 template<class T> cla