線性表的順序存儲結構的特點是,用物理上的鄰接關係表達邏輯上的前驅和後繼,因此可以通過簡單的公式獲取表中的任意元素的地址,但是在插入和刪除過程中需要移動大量元素,同時對存儲空間的利用不是很合理。接下來我用C++的模板式編程來實現線性表的基本功能
template<typename T>
class Linearlist
{
public:
Linearlist() {};
virtual bool Isempty()const { return length; };
virtual bool Find(int k, T &b)const = 0;
virtual bool Delete(int k, T &b) = 0;
virtual bool Insert(int k, const T&b) = 0;
virtual void Output(ostream &out) const = 0;
virtual ~Linearlist() {};
private:
int length;
};
這裏利用了抽象函數來實現線性表和鏈表的一些基本功能,其中判斷是否爲空不是抽象類,因爲判斷是否爲空的實現方式比較類似,通過多態可以實現。其他的爲純虛函數,便於接下來對線性表的表達。
template<typename T>
class LinearListSqu : public Linearlist<T>
{
public:
LinearListSqu(int Maxlistsize = 10);
~LinearListSqu() { if (element) { delete[]element; } };
virtual bool Isempty()const { return length == 0; };
virtual int Length()const { return length; };
virtual bool Find(int k, T &b)const;
virtual bool Delete(int k, T &b);
virtual bool Insert(int k, const T&b) ;
virtual void Output(ostream &out) const;
protected:
int Maxsize;
T *element;
int length;
};
這裏是抽象類的繼承,通過使用指針數組的方式來創建一個線性表,同時在結尾需要對指針的釋放,防止內存泄露,其中的思路比較簡單,最後還用到了輸出運算符重載(<<的重載),使其可以輸出對象的元素,簡化了後續的步驟。
class Nomem
{
public:
Nomem() { cout << "memory is not enough" << endl; };
~Nomem() {};
private:
};
class OutofBound
{
public:
OutofBound() { cout << "out of bound"; };
~OutofBound() {};
private:
};
這裏是檢查函數是否出現異常進行異常處理,採用了防禦式編程的思想
template<typename T>
LinearListSqu<T>::LinearListSqu(int Maxlistsize)
{
Maxsize = Maxlistsize;
try
{
element = new T[Maxsize];
}
catch (...)
{
throw Nomem();
}
length = 0;
}
template<typename T>
bool LinearListSqu<T>::Find(int k, T &b)const
{
if (k<1||k>length)
{
return false;
}
else
{
b = element[k - 1];
return true;
}
}
template<typename T>
void LinearListSqu<T>::Output(ostream &out) const
{
for (int i = 0; i < length; i++)
{
out << element[i] << " ";
}
}
template<typename T>
ostream &operator << (ostream &out,LinearListSqu<T>& b)
{
b.Output(out);
return out;
}
template<typename T>
bool LinearListSqu<T>::Insert(int k, const T &b)
{
if (k < 0 || k > length)
{
throw OutofBound();
}
if (length == Maxsize)
{
throw Nomem();
}
for (int i = length-1; i >=k; i--) //第幾個數字減一得到指針的序數,例如 1,2,3,4,5,6 轉化爲指針地址爲0,1,2,3,4,5
{
element[i + 1] = element[i];
} //最後一個數字減一後從k算起
element[k] = b; //在移出來的空位補一個元素
length++; //長度加一
return true;
}
template<typename T>
bool LinearListSqu<T>::Delete(int k, T &b)
{
if (Find(k ,b))
{
for (int i = k; i < length; i++)
{
element[i - 1] = element[i];
length--;
return true;
};
}
else throw OutofBound();
}
這裏便是對線性表功能的基本實現,具體思路很清晰,大家理解應該沒什麼問題
最後便是主函數的實現,用於測試該線性表的正確性。
int main()
{
try
{
LinearListSqu<int>L (5);
cout << "length==" << L.Length() << endl;
cout << "is empty" << L.Isempty() << endl;
bool ok = false;
ok = L.Insert(0, 2);
if (!ok)cout << "ok" << endl;
L.Insert(1, 6);
L.Insert(2, 8);
cout << "List = " << L << endl;
cout << "Is Empty" << L.Isempty() << endl;
int z;
L.Find(1, z);
cout << "First element is" << z << endl;
cout << "Length = " << L << endl;
L.Delete(1, z);
cout << "Delete element is" << z << endl;
cout << "List is" << L << endl;
}
catch (...)
{
cout << "An exception has occured" << endl;
}
}
這就是該線性表的簡單實現,筆者爲了練習而寫的,如果有不好的地方歡迎大家批評指正。