Tableau linéaire de la structure des données (structure de stockage séquentiel (tableau))

Deux ensembles de structures physiques de tables linéaires - structure de stockage séquentiel et structure de stockage en chaîne

La structure de stockage séquentiel de la table linéaire: utilisez un segment de membres de stockage d'adresses consécutifs pour stocker les éléments de données de la table linéaire à leur tour (la table linéaire stockée par le tableau est la table séquentielle)

#一个线性表的抽象类
#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的位置
 
}

Modifier la longueur d'un tableau à une dimension

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;//线性表元素个数
}

Constructeur et constructeur de copie de la classe 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);
}

La méthode de base de 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;
}

Recherche d'algorithme générique:
Dans un conteneur de type non-chaîne, vous pouvez trouver directement l'élément correspondant. La
fonction de recherche nécessite plusieurs paramètres: itérateur, valeur de l'indice et l'élément que vous recherchez
vecteur <int> a;
find (a .begin (), a.end (), 1);
Cette phrase signifie que du début de a à la fin, trouvez le premier élément avec une valeur de 1 et renvoyez un itérateur à cet élément.

Recherche a une large
gamme d'utilisations dans le conteneur de chaîne: find_first_of, find_last_of, find_not_first_of, find_not_last_of, etc.
Dans le type de chaîne, les paramètres requis comprennent également itérateurs, les indices et la chaîne à trouver Notez qu'il est une chaîne et ne peut pas. être recherché pour un seul caractère.
string a;
find (a.begin (), a.end (), "asd")
Cette phrase signifie que la première adresse de la chaîne avec la même sous-chaîne de "asd" se trouve dans a. Renvoie un itérateur pointant vers la première adresse de la chaîne.
find_last_of consiste à trouver le dernier,
find_not_first_of consiste à trouver la première adresse de la première chaîne qui n'est pas égale à "asd"

L'algorithme copy_backward est similaire à la copie en termes de comportement, sauf que son processus de copie s'exécute contre la copie. Le processus de copie commence à partir du dernier élément jusqu'à ce que le premier élément soit copié. En d'autres termes, l'opération de copie commence du dernier-1 jusqu'à la fin du premier. Ces éléments sont également copiés de l'arrière vers l'avant vers le conteneur cible, à partir de result-1, et copient toujours les derniers éléments.
Pour donner un exemple simple: étant donné le vecteur {0, 1, 2, 3, 4, 5}, nous devons maintenant copier les trois derniers éléments (3, 4, 5) dans les trois premiers (0, 1, 2) In la position, alors nous pouvons la définir comme ceci: mettre d'abord à la position 3, dernier à la position suivante de 5, et le résultat à la position de 3. De cette façon, la valeur de 5 sera copiée à la position de 2, puis 4 est copié à la position 1, et les 3 derniers sont copiés à la position 0. Nous pouvons être curieux de connaître les avantages de copy_backward () par rapport à l'algorithme copy () ordinaire qui commence à copier à partir du premier élément .
Une réponse est que lorsque la séquence se chevauche, vous pouvez utiliser copy () pour copier l'élément vers la position restante de la séquence de destination qui se chevauche, c'est-à-dire la position avant le premier élément de la séquence de destination. Si vous essayez d'utiliser l'algorithme copy () pour copier des éléments à droite de la même séquence, cette opération échouera, car les éléments copiés seront écrasés avant d'être copiés. Si vous voulez les copier vers la droite, vous pouvez utiliser copy_backward (), tant que l'itérateur de fin de la séquence de destination est à droite de l'itérateur de fin de la séquence source. La figure 2 illustre la différence entre les deux algorithmes lors de la copie d'éléments à droite de la séquence de chevauchement.

Je suppose que tu aimes

Origine blog.csdn.net/zangba9624/article/details/90482243
conseillé
Classement