數據結構之線性表操作(C++)

#include<iostream>
using namespace std;

//線性表的抽象數據類型定義
template <typename T>
class List {
public:
	virtual void clear() = 0;                //清空線性表
	virtual bool empty() const = 0;          //判空,真返回true,非空返回false
	virtual int size() const = 0;            //求線性表的長度
	virtual void insert(int i, const T& value) = 0; //在位序i處插入元素,值爲value
	virtual void remove(int i) = 0;          //位序i處刪除元素
	virtual int search(const T& value) const = 0;  //查找值爲value的元素第一次出現的位序
	virtual void traverse() const = 0;       //遍歷線性表
	virtual void inverse() = 0;              //匿置線性表
	virtual ~List() {};
};

//自定義異常處理類
class outOfRange :public exception {  //用於檢查範圍的有效性
public:
	const char* what() const throw() {
		return "ERROR! OUT OF RANGE.\n";
	}
};

class badSize :public exception {   //用於檢查長度的有效性
public:
	const char* what() const throw() {
		return "ERROR! BAD SIZE.\n";
	}
};

/*
順序表的類型定義
*/
template <typename elemType>                  //elemType爲順序表存儲的元素類型
class seqList : public List<elemType> {
private:
	elemType* data;                   //動態數組
	int curLength;                    //當前順序表中存儲的元素個數
	int maxSize;                      //順序表最大長度
	void resize();                    //表滿時,擴大表空間

public:
	seqList(int initSize = 10);       //構造函數
	seqList(seqList& s1);            //拷貝構造函數
	~seqList() { delete[] data; }        //析構函數
	void clear() { curLength = 0; }      //清空表
	bool empty() const { return curLength == 0; } //判空
	int size() const { return curLength; }        //返回順序表中當前存儲元素的個數

	void traverse() const;                            //遍歷順序表
	void inverse();                             //匿置順序表
	void insert(int i, const elemType& value);   //在位序i處插入值爲value的元素,表長加1

	void remove(int i);                         //刪除位序爲i處的元素,表長減一
	int search(const elemType& value) const;    //查找值爲value的元素第一次出現的位序

	bool Union(seqList<elemType> & B);		//合併順序表
};

/*
構造函數
*/
template <typename elemType>
seqList<elemType>::seqList(int initSize) {
	if (initSize <= 0) throw badSize();
	maxSize = initSize;
	data = new elemType[maxSize];
	curLength = 0;
}

/*
拷貝構造函數(自定義實現深拷貝)
*/
template <typename elemType>
seqList<elemType>::seqList(seqList & s1) {
	maxSize = s1.maxSize;
	curLength = s1.curLength;
	data = new elemType[maxSize];      //動態分配內存資源
	for (int i = 0; i < curLength; i++) {
		data[i] = s1.data[i];
	}
}

/*遍歷順序表*/
template <typename elemType>
void seqList<elemType>::traverse() const{
	if (empty()) cout << "is empty!" << endl;
	else {
		//cout << "Output element: " << endl;
		for (int i = 0; i < curLength; i++) {
			cout << data[i] << "  ";
		}
		cout << endl;
	}
}


/*
	查找值爲value的元素
	順序查找值爲value的元素在線性表中第一次出現的位置,遍歷線性表中元素
	若value==data[i],則查找成功,返回data[i]的位序,否則查找失敗返回-1.
*/
template <typename elemType>
int seqList<elemType>::search(const elemType& value) const {
	for (int i = 0; i < curLength; i++) {
		if (value == data[i]) return i;
	}
	return -1;             //查找失敗返回-1
}


/**
	插入運算:指定位序插入一個值爲value的新元素
*/
template <class elemType>
void seqList<elemType>::insert(int i, const elemType& value) {
	if (i<0 || i>curLength) throw outOfRange();
	if (curLength == maxSize) resize();
	for (int j = curLength; j > i; j--) {
		data[j] = data[j - 1];    //下標在[curLength-1...i]範圍內的元素後移一步.
	}
	data[i] = value;					//將值爲value的元素放置在位序爲i的位置上
	++curLength;					//表的長度加1
}

/*
	移除指定位置的值
*/
template <typename elemType>
void seqList<elemType>::remove(int i) {
	if (i<0 || i>curLength) throw outOfRange();
	for (int j = i; j < curLength-1; j++) {
		data[j] = data[j+1];
	}
	--curLength;       //表的長度減1
}

/*
	匿置運算:
*/
template <typename elemType>
void seqList<elemType>::inverse() {
	elemType temp;
	for (int i = 0; i < curLength / 2; i++) {
		temp = data[i];
		data[i] = data[curLength - i - 1];
		data[curLength - i - 1] = temp;
	}
}

/*
	擴大表空間
*/
template <typename elemType>
void seqList<elemType>::resize() {
	elemType* p = data;          //p指向原來順序表空間
	maxSize *= 2;				      //表空間擴大爲原來的二倍
	data = new elemType[maxSize];        //data指向新的表空間
	for (int i = 0; i < curLength; i++) {
		data[i] = p[i];		//元素拷貝
	}
	delete[] p;
}

/*
合併兩個有序線性表*/
template <typename elemType>
bool seqList<elemType>::Union(seqList<elemType> &B) {
	int  m, n, k, i, j;
	m = this->curLength;       //當前線性表長度
	n = B.curLength;			    //與之合併的線性表長度
	k = m + n - 1;                   //k爲結果線性表的工作指針(下標)
	i = m - 1;
	j = n - 1;                           //i,j分別爲指向線性表a和b的指針(下標)
	if (m + n > this->maxSize) {   //判斷a空間是否足夠大
		resize();                              //擴大表空間
	}
	while (i >= 0 && j >= 0)    //合併順序表,直到有一個表爲空
		if (data[i] >= B.data[j]) {
			data[k--] = data[i--];
		}
		else {
			data[k--] = B.data[j--];   //默認當前對象,this指針可以省略
		}
	while (j >= 0)
		data[k--] = B.data[j--];

	curLength = m + n;         //修改表的長度
	return true;
}


int main() {
	seqList<int> *sq = new seqList<int>(10);
	for (int i = 0; i < 5; i++) {
		sq->insert(i, i + 10);
	}
	cout << "線性表遍歷:   ";
	sq->traverse();

	cout << "線性表長度:   ";
	cout << sq->size();

	/*cout << "\n指定位置插入指定值:  " ;
	sq->insert(2, 1999);
	sq->traverse();*/

	/*cout << "線性表反轉:  ";
	sq->inverse();
	sq->traverse();*/

	cout << "\n查詢指定元素值的位序:  ";
	int num=sq->search(10);
	cout << num;

	cout << "\n移除指定位序處的值:   ";
	sq->remove(2);
	sq->traverse();

	cout << "合併兩n個線性表:   ";
	seqList<int> *B = new seqList<int>(10);
	for (int i = 0; i < 5;i++) {
		B->insert(i, 10 + i);
	}
	
	sq->Union(*B);
	sq->traverse();
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章