数据结构之队列(六)

        本文接上一篇,主要介绍“Deque”的另一种更高效的实现——DequeAsDoublyLinkedList。


一、操作效率之比

        前一篇中学到的DequeAsLinkedList,它的底层是采用的是单链表(点击打开链接)。单链表的特点是:“它只有一个指针域,指向后继者”,只能从前向后遍历,不能从后向前遍历。故删除head元素比较简单,直接删除指向的元素,并移动head指针即可,消耗为O(1);而删除tail元素,则需要先遍历整个链表,获取tail的前节点,删除尾元素后,还要修改它的前节点的next指针,并移动tail指针,遍历链表的时间消耗是O(n)。这样,DequeHead的时间是O(1);而DequeTail的时间是O(n)。

        要想提高DequeTail的效率,需要从底层进行修改,最好的办法是采用“双向链表”(点击打开链接),这样,在头尾的操作都是一样的,不足的是占用的内存更大,且需要对每个节点的prev和next指针进行管理。


二、DequeAsDoublyLinkedList

        接口声明

<span style="font-size:14px;">#pragma once
#include "Deque.h"
#include "DoublyLinkedList.h"
using namespace FoundationalDataStructure;

class DequeAsDoublyLinkedList : public Deque
{
public:
    DequeAsDoublyLinkedList();
    ~DequeAsDoublyLinkedList();

    void Purge();
    void Accept(Visitor &) const;

    Object & Head() const;
    Object & Tail() const;
    void Enqueue(Object &);
    void EnqueueHead(Object&);
    void EnqueueTail(Object &);
    Object & Dequeue();
    Object & DequeueHead();
    Object & DequeueTail();

protected:
    int CompareTo(Object const &) const;

private:
    DoublyLinkedList<Object*> list;
};
</span>

        接口实现

#include "DequeAsDoublyLinkedList.h"


DequeAsDoublyLinkedList::DequeAsDoublyLinkedList()
    : list()
{
}


DequeAsDoublyLinkedList::~DequeAsDoublyLinkedList()
{
    Purge();
}


void DequeAsDoublyLinkedList::Purge()
{
    if (IsOwner())
    {
        for (auto ptr = list.Head(); ptr != NULL; ptr = ptr->Next())
            delete ptr->Datum();
    }
    list.Purge();
    count = 0;
}

void DequeAsDoublyLinkedList::Accept(Visitor & visitor) const
{
    for (auto ptr = list.Head(); ptr != NULL && !visitor.IsDone(); ptr = ptr->Next())
        visitor.Visit(*ptr->Datum());
}

Object & DequeAsDoublyLinkedList::Head() const
{
    if (count == 0)
        throw std::domain_error("queue is empty");

    return *list.First();
}

Object & DequeAsDoublyLinkedList::Tail() const
{
    if (count == 0)
        throw std::domain_error("deque is empty");
    return *list.Last();
}

void DequeAsDoublyLinkedList::Enqueue(Object& object)
{
    Deque::Enqueue(object);
}

void DequeAsDoublyLinkedList::EnqueueHead(Object & object)
{
    list.Prepend(&object);
    ++count;
}

void DequeAsDoublyLinkedList::EnqueueTail(Object & object)
{
    list.Append(&object);
    ++count;
}

Object & DequeAsDoublyLinkedList::Dequeue()
{
    return Deque::Dequeue();
}

Object & DequeAsDoublyLinkedList::DequeueHead()
{
    if (count == 0)
        throw std::domain_error("queue is empty");

    Object &result = *list.First();
    list.Extract(&result);
    --count;
    return result;
}

Object & DequeAsDoublyLinkedList::DequeueTail()
{
    if (count == 0)
        throw std::domain_error("deque is empty");
    Object & result = *list.Last();
    list.Extract(&result);
    --count;
    return result;
}

int DequeAsDoublyLinkedList::CompareTo(Object const & object) const
{
    return -1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值