数据结构 顺序表
主要的成员函数:(除去构造函数以及析构函数)
函数名 | 功能 |
---|---|
int Size()const | 返回顺序表的大小 |
int Length()const | 返回实际上表中的元素数量 |
int Search(T&x)const | 返回表中x所在的位置 |
int Locate(int i)const | 返回i所代表的合法位置 |
bool getData(int i, T& x)const | 返回i处的值是否存在,若存在则存储至x中 |
void setData(int i, T& x) | 将i处的值设定为x |
bool insert(int i ,T& x) | 将x插入i的位置并返回插入是否成功 |
bool remove(int i, T& x) | 删除i处的值并返回是否删除成功,同时将删除的值存入x中 |
bool isEmpty() | 返回表是否为空 |
bool isFull() | 返回表是否满 |
其类定义:
#include<iostream>
#include<cstdlib>
using namespace std;
const int defaultSize = 100;
template<class T>
class SeqList{
protected:
T* data;
int maxSize;
int last;
void reSize(int newSize);
public:
SeqList(int size=defaultSize);//注意这里对size的默认初始化,此处也可以自己进行输入需要的大小
~SeqList();
SeqList(SeqList<T>& L);
int Size()const { return maxSize; }//标记为const能够提高程序的可读性,其保证了函数内部不改变类成员的值
int length()const { return last + 1; }
int Search(T& x)const;
int Locate(int i)const;
bool getData(int i, T& x)const;
void setData(int i, T& x);
bool insert(int i ,T& x);
bool remove(int i, T& x);
bool isEmpty() { return last == -1; }
bool isFull() { return last + 1 == maxSize; }
void input();//有input函数较易于构造新的顺序表
void output();
SeqList<T>operator=(SeqList<T>& L);
};
特别提出:
bool getData(int i, T& x)const;
这种写法不直接用函数值返回数据,而是使用bool型,更加安全。其可以先分析输入的数据合不合法再进行下一步操作,不容易出现危险
通过引用传值更加简便,易于操作
特别注意resize()函数:
原来本人写的:
template<class T>
void SeqList<T>::reSize(int newSize)
{
maxSize += newSize;
T* newData;
newData = new T[maxSize];
for (int i = 0; i <= last; i++)
newData[i] = data[i];
data = newData;
delete[]newData;
}
书上的代码:
template<class T>
void SeqList<T>::reSize(int newSize)
{
if (newSize <=0)
{
cerr << "无效大的数组大小" << endl; return;
}
if (newSize != maxSize)
{
T* newarray = new T[newSize];
if (newarray == NULL)
{
cerr << "分配错误" << endl; exit(1);
}
int n = last + 1;
T* temp1 = data;
T* temp2 = newarray;
while (n--)* temp2++ = *temp1++;
delete[]data;
data = newarray;
maxSize = newSize;
}
}
对比可知1.应该进行特殊值判断
2.在分配内存的时候一定要检查是否分配成功,因为有可能分配失败,影响后面的操作
3.注意再输出错误信息的时候使用cerr,不要使用cout
4.##如果像我这样操作首先会把存储的值删除掉,因为data和newdata指向的是同一个地址,其次应先进行delete操作,否则再进行转换后,原先的内存地址丢失,无法清理原来的内存
尽量再所有分配内存的地方先进行判断是否分配内存成功再进行下一步操作
总代码:
#include<iostream>
#include<cstdlib>
using namespace std;
const int defaultSize = 100;
template<class T>
class SeqList{
protected:
T* data;
int maxSize;
int last;
void reSize(int newSize);
public:
SeqList(int size=defaultSize);
~SeqList();
SeqList(SeqList<T>& L);
int Size()const { return maxSize; }
int length()const { return last + 1; }
int Search(T& x)const;
int Locate(int i)const;
bool getData(int i, T& x)const;
void setData(int i, T& x);
bool insert(int i ,T& x);
bool remove(int i, T& x);
bool isEmpty() { return last == -1; }
bool isFull() { return last + 1 == maxSize; }
void input();
void output();
SeqList<T>operator=(SeqList<T>& L);
};
template<class T>
void SeqList<T>::reSize(int newSize)
{
if (newSize <=0)
{
cerr << "无效大的数组大小" << endl; return;
}
if (newSize != maxSize)
{
T* newarray = new T[newSize];
if (newarray == NULL)
{
cerr << "分配错误" << endl; exit(1);
}
int n = last + 1;
T* temp1 = data;
T* temp2 = newarray;
while (n--)* temp2++ = *temp1++;
delete[]data;
data = newarray;
maxSize = newSize;
}
}
template<class T>
SeqList<T>::SeqList(int size) {
maxSize = size;
data = new T[maxSize];
last = -1;
}
template<class T>
SeqList<T>::~SeqList()
{
delete[]data;
}
template<class T>
SeqList<T>::SeqList(SeqList<T>& L)
{
maxSize = L.maxSize;
last = L.last;
data = new T[maxSize];
for (int i = 0; i <= last; i++)
{
data[i] = L.getData[i];
}
}
template<class T>
int SeqList<T>::Search(T& x)const
{
for (int i = 0; i <= last; i++)
{
if (data[i] == x)
{
return i+1;
}
}
return 0;
}
template<class T>
int SeqList<T>::Locate(int i)const//此处i是第几个元素
{
if (i >= 1 && i <= last + 1)return i;
return 0;
}
template<class T>
bool SeqList<T>::getData(int i, T& x)const
{
if (Locate(i)) {
x = data[i-1];
return true;
}
else
return false;
}
template<class T>
void SeqList<T>::setData(int i, T& x)
{
if (Locate(i))
{
data[i - 1] = x;
}
}
template<class T>
bool SeqList<T>::insert(int i, T& x)
{
if (isFull() || !Locate(i))return false;
for (int j = last; j >= i; j--)
{
data[j + 1] = data[j];
}
data[i] = x;
last++;
return true;
}
template<class T>
bool SeqList<T>::remove(int i, T& x)
{
if (!Locate(i)||isEmpty())return false;
x = data[i - 1];
for (int j = i; j <= last; j++)
{
data[j - 1] = data[j];
}
last--;
return true;
}
template<class T>
void SeqList<T>::input()
{
cout << "请输入元素数量以及元素的值" << endl;
cin >> last;
for (int i = 0; i <= last; i++)
cin >> data[i];
}
template<class T>
void SeqList<T>::output()
{
for (int i = 0; i <= last; i++)
cout << data[i] << " ";
cout << endl;
}
template<class T>//这里偷懒了,实际上与拷贝构造函数差不多
SeqList<T> SeqList<T>::operator=(SeqList<T>& L)
{
SeqList<T> temp(L);
return temp;
}