データ構造——リニアテーブル(シーケンス記憶構造(配列))
5703 ワード
リニアテーブルの物理構造の2つのセット
リニアテーブルの順序格納構造:一セグメントのアドレスで連続した記憶単員が順次リニアテーブルのデータ要素を記憶する(配列で記憶する線形表はシーケンステーブル)
findはstring容器の中で用途が広い:find_first_of,find_ラスター.of,find_not_first_of,find_not_ラスター.ofなどはstringタイプの中に、必要なパラメータもディズエ代機、下付き文字列と探している文字列があります.ここで注意してください.文字列です.単一文字を検索することはできません.string afind(a.begin()、a.end()、asd)という言葉は、aの中で最初の存在するサブストリングと「asd」のサブストリングが等しい文字列の先頭アドレスを見つけます.文字列の最初のアドレスを指すディエゼルを返します.find_ラスター.ofは最後の一つを見つけます.find_.not_first_ofは、最初の「asd」と同じではない文字列の最初のアドレスを見つけることです.
copy_backwardアルゴリズムはcopyと行為の面で似ていますが、コピープロセスはcopyと逆方向に進みます.コピープロセスは最後の要素からコピーし始めます.最初の元素がコピーされるまで.つまり、コピー操作は、ラスター-1から始まり、ファーストが終わるまで行われる.これらの要素も後から前の方にコピーされてターゲット容器に入り、リセット-1からlast-firstの要素をコピーしています.簡単な例を挙げると、vector{0、1、2、3、4、5}が知られています.最後の3つの要素(3、4、5)を前の3つ(0、1、2)の位置にコピーする必要があります.first設定値3の位置を、lastを5の次の位置に設定し、resultを3の位置に設定します.次に4を1の位置にコピーして、最後の3を0の位置にコピーします.普通の最初の要素からコピーしたcopy()アルゴリズムに比べて、copy_が気になります.バックウォードはどのようなメリットを提供していますか?一つの答えは、シーケンスが重なっている時に、copy()で要素を重ね合わせた目的のシーケンスの残りの位置、つまり、目的のシーケンスの最初の要素の前の位置にコピーすることができます.copy()アルゴリズムで要素を同じシーケンスの右側にコピーしようとしたら、この操作は成功しません.コピーされた要素はコピーする前に書き換えられますから.それらを右にコピーしたいなら、copy_を使ってもいいです.backward()は、目的のシーケンスの終了時に、シーケンサがソースシーケンスの終了時に、シーケンサの右側にある限りです.【図2】要素を重ね合わせたシーケンスの右側にコピーする場合の、この2つのアルゴリズムの違いを示す図である.
リニアテーブルの順序格納構造:一セグメントのアドレスで連続した記憶単員が順次リニアテーブルのデータ要素を記憶する(配列で記憶する線形表はシーケンステーブル)
#
#include
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
}
一次元配列の長さを変更します.template
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
copy(a,a+number,temp);// a temp//#include
delete [] a;
a=temp;// free delete , NULL, free delete ,
// , “ ” 。 NULL.
}
# arrayList , linearList , 。capacity( ) checkIndex.
template
class arrayList : public linearList
{
friend ostream& operator<& x);
public:
// ,
arrayList(int initialCapicity = 10);
arrayList(const arrayList&);
~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
arrayList::arraydList (int initialCapacity)
{
if(initialCapacity<1)
{ostringstream s;
s<0";
throw illegalParameterValue(s.str());
}
arrayLength = initialCapacity;
element = new T[arrayLength];
listSize = 0;
}
template
arrayList::arrayList (const arrayList& theList )
{
arrayLength = theList.arrayLength;
listSize = theList.listSize;
element = new T[arrayLength];
copy(theList.element,theList.element + listSize,element);
}
arrayListの基本的な方法template
void arrayList::checkIndex(int theIndex) const
{// 0 listSize-1
if(theIndex < 0 || theIndex >= listSize)
{ostringstream s
s << "index=" << theIndex << "size=" << listSize;
throw illegalIndex(s.str());
}
}
template
T& arrayList::get(int theIndex) const
{
checkIndex(theIndex);
return element[theIndex];
}
template
int arrayList::indexOf(const T& theElement) const
{
int theIndex = (int)(find(element,element+listSize,theElement)-element)
if(theIndex == listSize)
//
return -1;
else return theIndex;
}
template
void arrayList::erase(int theIndex)
{
checkIndex(theIndex);
// , theIndex
copy(element+theIndex+1,element+listSize,element+theIndex);
element[--listSize].~T();//
}
template
void arrayList::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<& x)
{
copy(element,element+listSize,ostream_iterator(s))
retrun s;
}
泛型アルゴリズムのfind:stringタイプではない容器の中で、直接に対応する元素を探し出すことができます.find関数はいくつかのパラメータが必要です.find(a.begin()、a.end()、1)この文はaの頭から尾までを表しています.最初の値は1の元素を見つけて、その元素を指すディズデーザーを返します.findはstring容器の中で用途が広い:find_first_of,find_ラスター.of,find_not_first_of,find_not_ラスター.ofなどはstringタイプの中に、必要なパラメータもディズエ代機、下付き文字列と探している文字列があります.ここで注意してください.文字列です.単一文字を検索することはできません.string afind(a.begin()、a.end()、asd)という言葉は、aの中で最初の存在するサブストリングと「asd」のサブストリングが等しい文字列の先頭アドレスを見つけます.文字列の最初のアドレスを指すディエゼルを返します.find_ラスター.ofは最後の一つを見つけます.find_.not_first_ofは、最初の「asd」と同じではない文字列の最初のアドレスを見つけることです.
copy_backwardアルゴリズムはcopyと行為の面で似ていますが、コピープロセスはcopyと逆方向に進みます.コピープロセスは最後の要素からコピーし始めます.最初の元素がコピーされるまで.つまり、コピー操作は、ラスター-1から始まり、ファーストが終わるまで行われる.これらの要素も後から前の方にコピーされてターゲット容器に入り、リセット-1からlast-firstの要素をコピーしています.簡単な例を挙げると、vector{0、1、2、3、4、5}が知られています.最後の3つの要素(3、4、5)を前の3つ(0、1、2)の位置にコピーする必要があります.first設定値3の位置を、lastを5の次の位置に設定し、resultを3の位置に設定します.次に4を1の位置にコピーして、最後の3を0の位置にコピーします.普通の最初の要素からコピーしたcopy()アルゴリズムに比べて、copy_が気になります.バックウォードはどのようなメリットを提供していますか?一つの答えは、シーケンスが重なっている時に、copy()で要素を重ね合わせた目的のシーケンスの残りの位置、つまり、目的のシーケンスの最初の要素の前の位置にコピーすることができます.copy()アルゴリズムで要素を同じシーケンスの右側にコピーしようとしたら、この操作は成功しません.コピーされた要素はコピーする前に書き換えられますから.それらを右にコピーしたいなら、copy_を使ってもいいです.backward()は、目的のシーケンスの終了時に、シーケンサがソースシーケンスの終了時に、シーケンサの右側にある限りです.【図2】要素を重ね合わせたシーケンスの右側にコピーする場合の、この2つのアルゴリズムの違いを示す図である.