学習データ構造 - 直鎖状の表で説明

ああ魏は最近、いくつかの時間のために落ち、そして今目覚めた、魏は、ブログを書くことを遵守する必要があります!
QAQのデータ構造を学ぶためにゼロからスタートする混同学ぶために最近のデータ構造、ああ魏

まず、ADTのテーブル直線(抽象)
(カテゴリ用テンプレートここ

template <class T>
class linearList
{
public:
    virtual ~linearList(){};
    virtual bool empty() const=0;//返回true,当且仅当线性表为空
    virtual int size() const=0;//返回线性表的元素个数
    virtual T& get(int theIndex) const=0;//返回索引为theIndex的元素
    virtual int indexOf(const T& theElement) const=0;//返回元素theElement第一次出现的索引
    virtual void erase(int theIndex)=0;
    virtual void insert(int theIndex,const T& theElement)=0;
    virtual void output(ostream& out) const=0;//把线性表插入输出流out
};

次の構造によって定義されたノードのリンクされたリストであります

template <class T>
struct chainNode
{
    T element;
    chainNode<T> *next;

    chainNode(){}
    chainNode(const T& element)
    {
        this->element=element;
    }
    chainNode(const T& element,chainNode<T>* next)
    {
        this->element=element;
        this->next=next;
    }
};

次は、リンクリストの定義です

template <class T>
class chain:public linearList<T>
{
public:
    chain(int initialCapacity=10);//构造函数
    chain(const chain<T>&);//复制构造函数
    ~chain();//析构函数
    //ADT方法
    bool empty() const
    {
        return listSize==0;
    }
    int size() const
    {
        return listSize;
    }
    T& get(int theIndex)const;
    int indexOf(const T& theElement) const;
    void erase(int theIndex);
    void insert(int theIndex,const T& theElement);
    void output(ostream& out) const;
protected:
    void checkIndex(int theIndex) const;//如果索引无效,抛出异常
    chainNode<T>* firstNode;//指向链表第一个结点的指针,注意并不是头结点
    int listSize;//线性表的元素个数
};

1. checkIndex機能を達成するために:

template<class T>
void chain<T>::checkIndex(int theIndex)const
{//确定索引在0和listSize-1之间
    if(theIndex<0||theIndex>=listSize)
    {
        ostringstream s;
        s<<"index="<<theIndex<<"size= "<<listSize;
        throw illegalIndex(s.str());
    }
}

2.リストコンストラクタ(時間複雑度 θ(1)

template<class T>
chain<T>::chain(int initialCapacity)
{
    if(initialCapacity<1)
    {
        ostringstream s;
        s<<"Initial capacity = "<<initialCapacity<<"Must be > 0";
        throw illegalParameterValue(s.str());
    }
    firstNode=NULL;
    listSize=0;
}

コピーコンストラクタ(時間複雑* O(MAX {LISTSIZE、theList.listSize}))の3 Aリスト

template<class T>
chain<T>::chain(const chain<T>& theList)
{
    listSize=theList.listSize;
    if(listSize==0)//链表theList为空
    {
        firstNode=NULL;
        return;
    }
    //若不为空
    chainNode<T>* sourceNode=theList.firstNode;//复制链表theList的节点
    firstNode=new chainNode<T>(sourceNode->element);//复制链表theList的首元素
    sourceNode=sourceNode->next;
    chainNode<T>* targetNode=firstNode;//当前链表的最后一个节点
    //复制剩余元素
    while(sourceNode!=NULL)
    {
        targetNode->next=new chainNode<T>(sourceNode->element);
        targetNode=targetNode->next;
        sourceNode=sourceNode->next;
    }
    targetNode->next=NULL;//链表结束
}

コピーコンストラクタは、説明するの:
ここに画像を挿入説明

4.リストデストラクタ(時間複雑度O(LISTSIZE))
デストラクタは、すべてのノードを削除することであり、この方法は、削除するヘッドノードから始まります

template<class T>
chain<T>::~chain()//删除链表的所有节点
{
    while(firstNode!=NULL)//删除首节点
    {
        chainNode<T>* nextNode=firstNode->next;
        delete firstNode;
        firstNode=nextNode;
    }
}

実装(時間計算量O(theIndex))5. get関数
この関数は、指定したインデックスの要素を見つけることです

template<class T>
T& chain<T>::get(int theIndex)const
{
    checkIndex(theIndex);//如果索引不存在,则抛出异常
    chainNode<T>* currentNode=firstNode;
    //移向所需要的节点
    for(int i=0;i<theIndex;i++)
        currentNode=currentNode->next;
    return currentNode->element;
}

実装は、(時間は、複雑さO(LISTSIZE))6のindexOf関数
この関数は、要素theElementの最初の発生を見つけるためのインデックスである
見つけるために見つからない場合、-1を返し、戻り率を

template<class T>
int chain<T>::indexOf(const T& theElement)const
{
    chainNode<T>* currentNode=firstNode;
    int index=0;
    //退出循环的条件:①没有找到,找到了最后,currentNode为空;②找到了
    while(currentNode!=NULL&&currentNode->element!=theElement)
    {
        currentNode=currentNode->next;
        index++;
    }
    //如果是由于没有找到退出的循环
    if(currentNode==NULL)
        return -1;
    //否则
    return index;
}

実装(時間複雑性O(theIndex))7.消去機能をれる
3つのケースに分け:
①:theIndex.setdefault <0またはtheIndex> = LISTSIZE。この操作で有効ではありません
②:削除非空のテーブルの0番目の要素ノード(第1要素)
③:削除他の要素ノード

template<class T>
void chain<T>::erase(int theIndex)
{
    checkIndex(theIndex);
    if(theIndex==0)//如果要删除首节点
    {
        firstNode=firstNode->next;
    }
    else
    {
        chainNode<T>* currentNode=firstNode;
        for(int i=0;i<theIndex-1;i++)//找到要删除的节点的前驱节点
        {
            currentNode=currentNode->next;
        }
        currentNode->next=currentNode->next->next;
    }
    listSize--;//将链表的个数减一
}

実現(時間計算量O(theIndex))8の機能、挿入
機能と同様の挿入・削除機能
(自分の皿Iの叫びによって書かれた教科書を参照)魏は、コードを書いているの下に

template<class T>
void chain<T>::insert(int theIndex,const T& theElement)
{
    chainNode<T>* tmpNode=new chainNode<T>(theElement);
    if(theIndex==0)
    {
        tmpNode->next=firstNode;
        firstNode=tmpNode;
    }
    else
    {
        chainNode<T>* p=firstNode;
        for(int i=0;i<theIndex-1;i++)
        {
            p=p->next;
        }
        tmpNode->next=p->next;
        p->next=tmpNode;//这两行代码位置不能换,因为如果先将p指向tmpNode,那之前p的后继就找不到了
    }
    listSize++;
}

教科書コードをお楽しみください。

template<class T>
void chain<T>::insert(int theIndex,const T& theElement)
{
    if(theIndex<0||theIndex>listSize)
    {
        ostringstream s;
        s<<"index="<<theIndex<<"size="<<listSize;
        throw illegalIndex(s.str());
    }
    if(theIndex==0)
        firstNode=new chainNode<T>(theElement,firstNode);
    else
    {
        chainNode<T>* p=firstNode;
        for(int i=0;i<theIndex-1;i++)
            p=p->next;
        p->next=new chainNode<T>(theElement,p->next);//太强了!
    }
    listSize++;
}

フォーム線形9.拡張抽象クラス
線膨張ADTテーブルの必要は、透明なクリアテーブル、テール一backにテーブル要素のような他の操作の数を含んでいます

template<class T>
class extendedLinearList::linearList<T>
{
public:
    virtual ~extendedLinearList(){}
    virtual void clear()=0;//清表
    virtual void push_back(const T& theElement)=0;//将元素theElement插到表尾
};

10.クリア機能の実現
lastNodeを高めるために説明extendedLinearListチェーン抽象ショートカット由来リストチェーンによって開発されたクラス、およびテールポインタはノードとして私たちは、クラスextendedChainを開発する必要があります
ここで明確な機能ですが

template<class T>
void extendedChain<T>::clear()
{
    //从首节点开始删除
    while(firstNode!=NULL)
    {
        chainNode<T>* nextNode=firstNode->next;
        delete firstNode;
        firstNode=nextNode;
    }
    listSize=0;
}

11.一back機能が達​​成するために

template<class T>
void extendedChain<T>::push_back(const T& theElement)
{
    chainNode<T>* newNode=new chainNode<T>(theElement,NULL);
    if(firstNode==NULL)
        firstNode=lastNode=newNode;//extendedChain中声明了尾结点lastNode
    else
    {
        lastNode->next=newNode;
        lastNode=newNode;
    }
    listSize++;
}
公開された32元の記事 ウォン称賛12 ビュー1377

おすすめ

転載: blog.csdn.net/qq_18873031/article/details/103065219