1. 程式人生 > >【資料結構】線性表(陣列實現)

【資料結構】線性表(陣列實現)

1、線性表


2、線性表的抽象資料型別描述


3、線性表的陣列描述

按照上述抽象描述,定義一個模板類來描述上述的抽象描述。

template<class T>
class LinearList
{
public:
	LinearList(int MaxListSize = 10);			//建構函式
	~LinearList()								//解構函式
	{
		delete []element;						//刪除堆空間
	}
	
	bool isEmpty() const 						//判斷線性表是否為空
	{
		return (length == 0);					
	}
	
	int Length() const 							//線性表長度
	{
		return length;
	}
	
	bool Find(int k, T& x) const;	    		//返回第k個元素到x中
	
	int Search(const T& x) const;				//返回x所在的位置
	
	LinearList<T>& Delete(int k, T& x); 		//刪除第k個元素並將它返回到x中
	
	LinearList<T>& Insert(int k, const T& x); 	//在第k個元素之後的位置插入x
	
	void Output(ostream& out) const;			//輸出線性表內容
	
private:
	int MaxSize;								//線性表可容納最大長度
	int length;									//線性表中非空的長度		
	T *element;									//線性表陣列頭指標
};

下面依次分析各種操作。

3.1 Create()操作

Create()建立一個空線性表,對應的就是類的建構函式操作。建構函式裡面首先要的就是對空間的分配,當然要確定類成員變數的值。

/*
建構函式
*/
template<class T>
LinearList<T>::LinearList(int MaxListSize)
{
	MaxSize = MaxListSize;
	element = new T[MaxSize];
	length = 0;
}

3.2 Destory()操作

Destory()操作主要就是對線性表物件分配的堆空間進行回收。

~LinearList()								//解構函式
	{
		delete []element;				        //刪除堆空間
	}

3.3 isEmpty()操作

isEmpty()操作很簡單,就是判斷線性表是否為空。檢查是否為空只需檢查類length的值是否為零。

bool isEmpty() const 						//判斷線性表是否為空
	{
		return (length == 0);					
	}

3.4 Length()操作

Length()操作就是要返回線性表的所含元素的個數。

int Length() const 							//線性表長度
	{
		return length;
	}

3.5 Find()操作

bool Find(int k, T& x) const;操作是將線性表中的第k個元素返回到x中,這裡操作裡面要注意的就是判斷標號k是否是線上性表的範圍內,若不在範圍內,則返回false。

/*
返回第k個元素到x中
*/
template<class T>
bool LinearList<T>::Find(int k, T& x) const
{
	if(k > length || k < 0)
		return false;
	x = element[k];
	return true;
}

3.6 Search()

Search()函式就是查詢傳入的引數是否線上性表中,如果不在返回-1,如果線上性表中則返回該元素線上性表中的索引。

/*
遍歷整個陣列,發現被查詢元素和陣列中元素匹配則返回該元素位置
如果在陣列中沒有發現被查詢元素,則返回-1
*/
template<class T>
int LinearList<T>::Search(const T& x) const
{
	for(int i=0; i<length; ++i)
	{
		if(x == element[i]) 
			return i;
	}
	return -1;
}

3.7 Delete()操作

Delete()操作要從線性表中刪除一個元素,如果有該元素就刪除,並返回到x;如果不存在該元素則丟擲異常。要注意長度的變化。

/*
從線性表中刪除一個元素
*/
template<class T>
LinearList<T>& LinearList<T>::Delete(int k, T& x)
{
	if(!Find(k, x)) 									//如果序列中沒有該元素則丟擲異常
	{
		throw "Out of Bounds";
	}
	//將第k個元素後的元素依次往前移動一個位置,覆蓋掉第k個元素
	for(int i = k+1; i<length; ++i)
	{
		element[i-1] = element[i];
	}
	length -= 1;										//線性表長度減少一個長度
	return *this;
}

3.8 Insert()操作

Insert()是在索引k的後面插入一個元素,返回當前線性表;需要檢查k是否在可插入的範圍內。重要的是要檢查當前線性表分配的空間是否已經儲存滿了。要注意長度的變化。

/*
在第k個元素的後面插入一個元素
*/
template<class T>
LinearList<T>& LinearList<T>::Insert(int k, const T& x)
{
	if(k > length || k < 0)
	{
		//丟擲異常
		throw "插入元素位置不正確!";
	}
	if(length == MaxSize)
	{
		//丟擲異常,空間不足
		throw "空間不足";
	}
	//將第k個元素後面的元素都往後移動一個單位
	for(int i=length; i>k; --i)
	{
		element[i] = element[i-1];
	}
	element[k] = x;
	length += 1;
	return *this;
}

3.9 Output()操作

為了使線性表資料視覺化。

/*
輸出線性表內容
*/
template<class T>
void LinearList<T>::Output(ostream& out) const
{
	out << endl <<"print list element: " << endl;
	for (int i = 0; i < length; i++)
	{
		out << element[i] << " ";
	}
	out << endl;
}

4、實現原始碼

tips:模板類的定義和實現要放在一個檔案裡面,不然會報錯!!

.h檔案

#ifndef __LINEARLIST_H__
#define __LINEARLIST_H__

#include <iostream>
using namespace std;


template<class T>
class LinearList
{
public:
	LinearList(int MaxListSize = 10);			//建構函式
	~LinearList()								//解構函式
	{
		delete []element;						//刪除堆空間
	}
	
	bool isEmpty() const 						//判斷線性表是否為空
	{
		return (length == 0);					
	}
	
	int Length() const 							//線性表長度
	{
		return length;
	}
	
	bool Find(int k, T& x) const;	    		//返回第k個元素到x中
	
	int Search(const T& x) const;				//返回x所在的位置
	
	LinearList<T>& Delete(int k, T& x); 		//刪除第k個元素並將它返回到x中
	
	LinearList<T>& Insert(int k, const T& x); 	//在第k個元素之後的位置插入x
	
	void Output(ostream& out) const;			//輸出線性表內容
	
private:
	int MaxSize;								//線性表可容納最大長度
	int length;									//線性表中非空的長度		
	T *element;									//線性表陣列頭指標
};


/*
建構函式
*/
template<class T>
LinearList<T>::LinearList(int MaxListSize)
{
	MaxSize = MaxListSize;
	element = new T[MaxSize];
	length = 0;
}

/*
返回第k個元素到x中
*/
template<class T>
bool LinearList<T>::Find(int k, T& x) const
{
	if(k > length || k < 0)
		return false;
	x = element[k];
	return true;
}

/*
遍歷整個陣列,發現被查詢元素和陣列中元素匹配則返回該元素位置
如果在陣列中沒有發現被查詢元素,則返回-1
*/
template<class T>
int LinearList<T>::Search(const T& x) const
{
	for(int i=0; i<length; ++i)
	{
		if(x == element[i]) 
			return i;
	}
	return -1;
}

/*
從線性表中刪除一個元素
*/
template<class T>
LinearList<T>& LinearList<T>::Delete(int k, T& x)
{
	if(!Find(k, x)) 									//如果序列中沒有該元素則丟擲異常
	{
		throw "Out of Bounds";
	}
	//將第k個元素後的元素依次往前移動一個位置,覆蓋掉第k個元素
	for(int i = k+1; i<length; ++i)
	{
		element[i-1] = element[i];
	}
	length -= 1;										//線性表長度減少一個長度
	return *this;
}


/*
在第k個元素的後面插入一個元素
*/
template<class T>
LinearList<T>& LinearList<T>::Insert(int k, const T& x)
{
	if(k > length || k < 0)
	{
		//丟擲異常
		throw "插入元素位置不正確!";
	}
	if(length == MaxSize)
	{
		//丟擲異常,空間不足
		throw "空間不足";
	}
	//將第k個元素後面的元素都往後移動一個單位
	for(int i=length; i>k; --i)
	{
		element[i] = element[i-1];
	}
	element[k] = x;
	length += 1;
	return *this;
}

/*
輸出線性表內容
*/
template<class T>
void LinearList<T>::Output(ostream& out) const
{
	out << endl <<"print list element: " << endl;
	for (int i = 0; i < length; i++)
	{
		out << element[i] << " ";
	}
	out << endl;
}

/*
過載<<運算子
*/
template <class T>
ostream& operator<<(ostream& out, const LinearList<T>& x)
{
	x.Output(out);
	return out;
}


#endif // !__LINEARLIST_H__


.c檔案
#include <iostream>
#include "LinearList.h"
using namespace std;


int main()
{
	LinearList<int> list(10);
	cout << "Length = " << list.Length() << endl;
	cout << "IsEmpty = " << list.isEmpty() << endl;
	list.Insert(0,2);
	list.Insert(1,6);
	list.Insert(2,8);
	list.Insert(0,4);
	list.Output(cout);
	int x;
	list.Delete(2,x);
	list.Output(cout);
	cout << "IsEmpty = " << list.isEmpty() << endl;
	return 0;
}



執行結果: