数据结构之“Ordered List and Sorted List”(二)

来源:互联网 发布:股票价格提醒软件 编辑:程序博客网 时间:2024/06/03 01:10

        本文主要学习“Ordered List”的两种实现——“ListAsArray”(基于动态数组:点击打开链接)和“ListAsLinkedList”(基于指针)。


一、“ListAsArray”(点击打开链接)

        基于数组的List,有大小限制。

<span style="font-size:14px;">#pragma once#include "List.h"#include "DynamicArray.h"using namespace FoundationalDataStructure;class ListAsArray : public virtual OrderedList{public:    ListAsArray(unsigned int);    ~ListAsArray();    void Purge();    void Accept(Visitor &) const;    void Insert(Object &);    Object & operator[](unsigned int) const;    Object & operator[](Position const &) const;    bool IsMemeber(Object const &) const;    Object & Find(Object const &) const;    Position & FindPosition(Object const &) const;    void Withdraw(Object &);    void Withdraw(Position const &);    void InsertAfter(Position const &, Object &);    void InsertBefore(Position const &, Object &);    friend class Pos;protected:    int CompareTo(Object const &) const;protected:    Array<Object* > array;    class Pos;};class ListAsArray::Pos : public Position{public:    Pos(ListAsArray const &, unsigned int);    void Reset();    bool IsDone() const;    Object& operator * () const;    void operator ++();    friend class ListAsArray;    friend class SortedListAsArray;protected:    const ListAsArray & list;    unsigned int offset;};</span>


        实现代码如下,需要注意的是:

        1,默认插入在List尾部;

        2,“InsertAfter”和“InsertBefore”是通过移位来实现的。

        3,“remove”也是通过移位来实现。


<span style="font-size:14px;">#include "stdafx.h"#include "ListAsArray.h"#include "NullObject.h"ListAsArray::ListAsArray(unsigned int size)    : array(size){}ListAsArray::~ListAsArray(){    Purge();}void ListAsArray::Purge(){    if (IsOwner())    {        for (unsigned int i = 0; i < count; ++i)            delete array[i];    }    count = 0;}void ListAsArray::Accept(Visitor & visitor) const{    for (unsigned int i = 0; i < count && !visitor.IsDone(); ++i)        visitor.Visit(*array[i]);}void ListAsArray::Insert(Object & object){    if (count == array.Length())        throw std::domain_error("list is full");    array[count] = &object;    // insert at the end    ++count;}Object & ListAsArray::operator[](unsigned int offset) const{    if (offset > count)        throw std::out_of_range("invalid offset");    return *array[offset];}Object & ListAsArray::operator[](Position const & arg) const{    Pos const & position = dynamic_cast<Pos const &>(arg);    if (&position.list != this || position.offset >= count)        throw std::invalid_argument("invalid position");    return *array[position.offset];}bool ListAsArray::IsMemeber(Object const & object) const{    for (unsigned int i = 0; i < count; ++i)        if (array[i] == &object)    // compare with the address of a object            return true;    return false;}Object & ListAsArray::Find(Object const & object) const{    for (unsigned int i = 0; i < count; ++i)        if (*array[i] == object)    // compares equal to the given object            return *array[i];    return NullObject::Instance();}Position & ListAsArray::FindPosition(Object const & object) const{    unsigned int i = 0;    while (i < count && *array[i] != object)    // compares equal to the given object        ++i;    return *new Pos(*this, i);}void ListAsArray::Withdraw(Object & object){    if (count == 0)        throw std::domain_error("list is empty");    unsigned int i = 0;    while (i < count && array[i] != &object)        ++i;    if (i == count)        throw std::invalid_argument("object is not found");    for (; i < count - 1; ++i)        array[i] = array[i + 1];    --count;}void ListAsArray::Withdraw(Position const & arg){    Pos const & position = dynamic_cast<Pos const &>(arg);    if (count == 0)        throw std::domain_error("list is empty");    if (&position.list != this || position.offset >= count)        throw std::invalid_argument("invalid position");    for (unsigned int i = position.offset; i < count - 1U; ++i)        array[i] = array[i + 1];    --count;}void ListAsArray::InsertAfter(Position const & arg, Object & object){    Pos const & position = dynamic_cast<Pos const &>(arg);    if (count == array.Length())        throw std::domain_error("list is full");    if (&position.list != this || position.offset >= count)        throw std::invalid_argument("invalid position");    unsigned int const insertPosition = position.offset + 1;    for (unsigned int i = count; i > insertPosition; --i)        array[i] = array[i - 1];    array[insertPosition] = &object;    ++count;}void ListAsArray::InsertBefore(Position const & arg, Object & object){    Pos const & position = dynamic_cast<Pos const &>(arg);    if (count == array.Length())        throw std::domain_error("list is full");    if (&position.list != this || position.offset >= count)        throw std::invalid_argument("invalid position");    unsigned int const insertPosition = position.offset;    for (unsigned int i = count; i >= insertPosition; --i)        array[i] = array[i - 1];    array[insertPosition] = &object;    ++count;}int ListAsArray::CompareTo(Object const & object) const{    return -1;}// the implement of the ListAsArray::PosListAsArray::Pos::Pos(ListAsArray const & _list, unsigned int _offset)    : list(_list)    , offset(_offset){}bool ListAsArray::Pos::IsDone() const{    return offset >= list.count;}Object&  ListAsArray::Pos::operator * () const{    if (offset < list.count)        return *list.array[offset];    else        return NullObject::Instance();}void ListAsArray::Pos::operator++(){    if (offset < list.count)        ++offset;}void ListAsArray::Pos::Reset(){    offset = 0;}</span>


二、“ListAsLinkedList”()
        基于链表的实现更加灵活。

<span style="font-size:14px;">#pragma once#include "List.h"#include "LinkedList.h"using namespace FoundationalDataStructure;class ListAsLinkedList : public virtual List{public:    ListAsLinkedList();    ~ListAsLinkedList();    void Purge();    void Accept(Visitor &) const;    void Insert(Object &);    Object & operator[](unsigned int) const;    Object & operator[](Position const &) const;    bool IsMemeber(Object const &) const;    Object & Find(Object const &) const;    Position & FindPosition(Object const &) const;    void Withdraw(Object &);    void Withdraw(Position const &);    void InsertAfter(Position const &, Object &);    void InsertBefore(Position const &, Object &);    friend class Pos;protected:    int CompareTo(Object const &) const;protected:    LinkedList<Object* > linkedList;    class Pos;};class ListAsLinkedList::Pos : public Position{public:    Pos(ListAsLinkedList const &, Node<Object*> const *);    void Reset();    bool IsDone() const;    Object& operator * () const;    void operator ++();    friend class ListAsLinkedList;    friend class SortedListAsLinkedList;protected:    const ListAsLinkedList & list;    Node<Object*> const * ptr;};</span>

        基于链表的实现,添加或删除项的时候,直接“打开链接”和“添加链接”或“删除链接”即可。实现代码:

<span style="font-size:14px;">#include "stdafx.h"#include "ListAsLinkedList.h"#include "NullObject.h"ListAsLinkedList::ListAsLinkedList(){}ListAsLinkedList::~ListAsLinkedList(){    Purge();}void ListAsLinkedList::Purge(){    if (IsOwner())    {        for (auto ptr = linkedList.Head(); ptr != NULL; ptr = ptr->Next())            delete ptr->Datum();    }    linkedList.Purge();    count = 0;}void ListAsLinkedList::Accept(Visitor & visitor) const{    for (auto ptr = linkedList.Head(); ptr != NULL && !visitor.IsDone(); ptr = ptr->Next())        visitor.Visit(*ptr->Datum());}void ListAsLinkedList::Insert(Object & object){    linkedList.Append(&object);    ++count;}Object & ListAsLinkedList::operator[](unsigned int offset) const{    if (offset > count)        throw std::out_of_range("invalid offset");    unsigned int i = 0;    auto ptr = linkedList.Head();    while (i < offset && ptr != NULL)    {        ptr = ptr->Next();        ++i;    }    if (ptr == NULL)        throw std::logic_error("should never happen");    return *ptr->Datum();}Object & ListAsLinkedList::operator[](Position const & arg) const{    Pos const & position = dynamic_cast<Pos const &>(arg);    if (&position.list != this || position.ptr == NULL)        throw std::invalid_argument("invalid position");    return *position.ptr->Datum();}bool ListAsLinkedList::IsMemeber(Object const & object) const{    for (auto ptr = linkedList.Head(); ptr != NULL; ptr = ptr->Next())        if (ptr->Datum() == &object)    // compare with the address of a object            return true;    return false;}Object & ListAsLinkedList::Find(Object const & object) const{    for (auto ptr = linkedList.Head(); ptr != NULL; ptr = ptr->Next())        if (*ptr->Datum() == object)    // compares equal to the given object            return *ptr->Datum();    return NullObject::Instance();}Position & ListAsLinkedList::FindPosition(Object const & object) const{    auto ptr = linkedList.Head();    while (ptr && *ptr->Datum() != object)    // compares equal to the given object        ptr = ptr->Next();    return *new Pos(*this, ptr);}void ListAsLinkedList::Withdraw(Object & object){    if (count == 0)        throw std::domain_error("list is empty");    linkedList.Extract(&object);    --count;}void ListAsLinkedList::Withdraw(Position const & arg){    Pos const & position = dynamic_cast<Pos const &>(arg);    if (&position.list != this || position.ptr == NULL)        throw std::invalid_argument("invalid position");    linkedList.Extract(position.ptr->Datum());    --count;}void ListAsLinkedList::InsertAfter(Position const & arg, Object & object){    Pos const & position = dynamic_cast<Pos const &>(arg);    if (&position.list != this || position.ptr == NULL)        throw std::invalid_argument("invalid position");    linkedList.InsertAfter(position.ptr, &object);    ++count;}void ListAsLinkedList::InsertBefore(Position const & arg, Object & object){    Pos const & position = dynamic_cast<Pos const &>(arg);    if (&position.list != this || position.ptr == NULL)        throw std::invalid_argument("invalid position");    linkedList.InsertBefore(position.ptr, &object);    ++count;}int ListAsLinkedList::CompareTo(Object const & object) const{    return -1;}// the implement of the ListAsLinkedList::PosListAsLinkedList::Pos::Pos(ListAsLinkedList const & _list, Node<Object*> const * _ptr)    : list(_list)    , ptr(_ptr){}bool ListAsLinkedList::Pos::IsDone() const{    return ptr == NULL;}Object&  ListAsLinkedList::Pos::operator * () const{    if (ptr)        return *ptr->Datum();    else        return NullObject::Instance();}void ListAsLinkedList::Pos::operator++(){    if (ptr)        ptr = ptr->Next();}void ListAsLinkedList::Pos::Reset(){    ptr = list.linkedList.Head();}</span>



0 0
原创粉丝点击