データ構造-線形テーブル(シーケンシャルストレージ構造(配列))

線形テーブルの2セットの物理構造-シーケンシャルストレージ構造とチェーンストレージ構造

線形テーブルの順次ストレージ構造:連続するアドレスストレージメンバーのセグメントを使用して、線形テーブルのデータ要素を順番に格納します(配列によって格納される線形テーブルは順次テーブルです)

#一个线性表的抽象类
#include<iostream>
class linerList{
   public:
      virtual ~linerList() {};            
      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;  //删除索引为theIndex的元素
      virtual void insert(int theIndex, const T& theElement)=0;//把theElement插入线性表中索引为theIndex的位置
 
}

1次元配列の長さを変更する

template<class T>
void changedLength1D(T* a, int oldLength, int newLength)
{
   if (newLength<0)
      throw illegalParameterValue("new length must be >=0");
   T* temp=new T[newLength];
   int number=min(oldLength,newLength);//#include <algorithm>
   copy(a,a+number,temp);//将a复制到temp//#include <algorithm>
   delete [] a;
   a=temp;//指针被free或者delete后,没有置为NULL, free和delete只是把指针所指向的内存给释放掉,
           //并没有把指针本身干掉,此时指针指向的是“垃圾”内存。释放后的指针应该被置为NULL.否则造成内存泄漏
}
#类arrayList是一个具体类,所以他必须实现抽象类linearList的所有方法,并且还包含基类没有的方法。capacity(给出数组长度)和checkIndex.

template<class T>
class arrayList : public linearList<T>
{
   friend ostream& operator<<(ostream&, const arrayList<T>& x);
   public:
//构造函数,复制构造函数和析构函数
      arrayList(int initialCapicity = 10);
      arrayList(const arrayList<T>&);
      ~arrayList() {delete [] element;}

//ADT方法
      bool empty() const {return listSize == 0;}
      int size()  const {return listSize;}
      T& get(int index)const ;
      int indexOf(const T& theElement) const;
      void erase(int theIndex);
      void insert(int theIndex, const T& theElement );
      
      
//其他方法
      int capacity()const {redturn arrayLength;}
      
   projected:
      void checkIndex(int theIndex) const;//若索引无效则抛出异常
      T* element;//存储线性表元素的一维数组
      int arrayLength;//一维数组的容量
      int listSize;//线性表元素个数
}

クラスarrayListのコンストラクターとコピーコンストラクター

template<class T>
arrayList<T>::arraydList (int initialCapacity)
{
   if(initialCapacity<1)
   {ostringstream s;
    s<<"Initial capacity="<<initialCapacity<<"Must be>0";
    throw illegalParameterValue(s.str());
    }
   arrayLength = initialCapacity;
   element = new T[arrayLength];
   listSize = 0;
}

template<class T>
arrayList<T>::arrayList (const arrayList<T>& theList )
{
   arrayLength = theList.arrayLength;
   listSize = theList.listSize;
   element = new T[arrayLength];
   copy(theList.element,theList.element + listSize,element);
}

arrayListの基本的なメソッド

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

template<class T>
T& arrayList<T>::get(int theIndex) const
{
   checkIndex(theIndex);
   return element[theIndex];
}

template<class T>
int arrayList<T>::indexOf(const T& theElement) const
{
   int theIndex = (int)(find(element,element+listSize,theElement)-element)
   if(theIndex == listSize)
    //没有找到
     return -1;
   else return theIndex;
}

template<class T>
void arrayList<T>::erase(int theIndex)
{
   checkIndex(theIndex);
   //有效索引,移动其索引大于theIndex的元素
   copy(element+theIndex+1,element+listSize,element+theIndex);
   element[--listSize].~T();//调用析构函数
}


template<class T>
void arrayList<T>::insert(int theIndex, const T& theElement )
{
   if(theIndex < 0 || theIndex > listSize)
    {//无效索引
     ostringstream s;
     s << "index="  << theIndex << "size=" << listSize;
     throw illegalIndex(s.str());
    }

//有效索引,确定数组是否已满
   if(listSize == arrayLength)
   {//数组空间已满,数组长度增倍
    changeLength1D(element,arrayLength,arrayLength*2);
    arrayLength *= 2;
   }

//把元素向右移动一个位置
   copy_backward(element+thedIndex,element+listSize,element+listSize+1);
   element[theIndex] = theElement;
   listSize++;   
}

ostream& operator<<(ostream& s, const arrayList<T>& x)
{
   copy(element,element+listSize,ostream_iterator<T>(s))
   retrun s;
}

遺伝的アルゴリズムの検索:
非文字列型のコンテナーでは、対応する要素を直接検索できます。
検索関数には、イテレーター、添え字値、および探している要素のいくつかのパラメーターが必要です。vector
<int> a;
find(a .begin()、a.end()、1);
この文は、aの最初から最後まで、値が1の最初の要素を見つけて、その要素にイテレーターを返すことを意味します。

Findは、文字列コンテナでさまざま
用途があります:find_first_of、find_last_of、find_not_first_of、find_not_last_ofなど。
文字列タイプでは、必要なパラメータには、イテレータ、添え字、および検索する文字列も含まれます。これは文字列であり、できないことに注意してください。 1文字を検索します。
string a;
find(a.begin()、a.end()、 "asd")
この文は、「asd」と同じ部分文字列を持つ文字列の最初のアドレスが。にあることを意味します。文字列の最初のアドレスを指すイテレータを返します。
find_last_ofは最後の
アドレスを検索しfind_not_first_ofは「asd」と等しくない最初の文字列の最初のアドレスを検索します。

copy_backwardアルゴリズムは、そのコピープロセスがコピーに対して逆に実行されることを除いて、動作の点でコピーに似ています。コピープロセスは、最後の要素から最初の要素がコピーされるまで開始されます。つまり、コピー操作はlast-1からfirstの終わりまで開始されます。これらの要素も、result-1から開始して、後ろから前にターゲットコンテナにコピーされ、常に最後から最初の要素をコピーします。
簡単な例を挙げると、ベクトル{0、1、2、3、4、5}が与えられた場合、最後の3つの要素(3、4、5)を最初の3つの要素(0、1、2)にコピーする必要があります。位置を設定すると、次のように設定できます。最初に3の位置に設定し、最後に5の位置に設定し、結果を3の位置に設定します。このようにして、5の値がの位置にコピーされます。 2、次に4が1の位置にコピーされ、最後の3が0の位置にコピーされます。最初からコピーを開始する通常のcopy()アルゴリズムと比較したcopy_backward()の利点について興味があるかもしれません。要素
1つの答えは、シーケンスがオーバーラップする場合、copy()を使用して、オーバーラップする宛先シーケンスの残りの位置、つまり、宛先シーケンスの最初の要素の前の位置に要素をコピーできるということです。copy()アルゴリズムを使用して同じシーケンスの右側に要素をコピーしようとすると、コピーされた要素がコピーされる前に上書きされるため、この操作は成功しません。それらを右側にコピーする場合は、宛先シーケンスの終了イテレーターがソースシーケンスの終了イテレーターの右側にある限り、copy_backward()を使用できます。図2は、重複するシーケンスの右側に要素をコピーする場合の2つのアルゴリズムの違いを示しています。

おすすめ

転載: blog.csdn.net/zangba9624/article/details/90482243