线性表常规的一些常用操作
狄泰软件数据结构笔记
结构层次
线性表存储结构抽象实现(静态)
list.h
#ifndef __LIST_H
#define __LIST_H
#include "Object.h"
namespace DTLib {
template <typename T>
class List :public Object
{
public:
virtual bool insert(int i, const T& e) = 0;
virtual bool remove(int i) = 0;
virtual bool set(int i, const T& e) = 0;
virtual bool get(int i, T& e) const = 0;
virtual int lenght() const = 0;
virtual void clear() = 0;
};
}
#endif // !__List_H
SeqList.h
#ifndef __SEQLIST_H
#define __SEQLIST_H
#include "List.h"
#include "Exception.h"
namespace DTLib {
template <typename T>
class SeqList :public List<T>
{
protected:
T* m_array;//顺序存储空间
int m_length;//当前线性表长度
public:
bool insert(int i, T& e)
{
bool ret = ((0 <= i) && (i <= m_length));
ret = ret && (m_length < capacity());
if (ret)
{
for (int p = m_length - 1; p >= i; p--)
{
m_array[p + 1] = m_array[p];
}
m_array[i] = e;
m_array++;
}
return ret;
}
//尾部插入
bool insert(const T& e)
{
return insert(m_length, e);
}
bool remove(int i)
{
bool ret = ((0 <= i) && (i <= m_length));
if (ret)
{
for (int p = i; p < m_length; p++)
{
m_array[p] = m_array[p + 1];
}
m_length--;
}
return ret;
}
bool set(int i, const T& e)
{
bool ret = ((0 <= i) && (i <= m_length));
if (ret)
{
m_array[i] = e;
}
return set;
}
bool get(int i, T& e) const
{
bool ret = ((0 <= i) && (i <= m_length));
if (ret)
{
e = m_array[i];
}
return ret;
}
int length() const
{
return m_length;
}
//清空线性表
void clera()
{
m_length = 0;
}
//数组访问方式
T& operator[] (int i)
{
if ((0 <= i) && (i < m_length))
{
return m_array[i];
}
else
{
//如果i越界抛出异常
THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter i is invalid ...");
}
}
T operator[] (int i) const
{
//由于代码一样
/*
if ((0 <= i) && (i < m_length))
{
return m_array[i];
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter i is invalid ...");
}
*/
//代码复用T& operator[] (int i)重载函数
//去掉const属性
return (const_cast<SeqList<T>&>(*this))[i];
}
//存储空间,子类实现
//当前类不能生产对象,但可以定义为指针
virtual int capacity() const = 0;
};
}
#endif
测试main.cpp
#include <iostream>
//#include "SmartPointer.h"
//#include"Exception.h"
//#include"Object.h"
#include "SeqList.h"
using namespace std;
using namespace DTLib;
int main()
{
SeqList<int>* sp = NULL;
return 0;
}
staticlist类模板
staticlist.h
#ifndef __STATICLIST_H
#define __STATICLIST_H
#include "SeqList.h"
namespace DTLib {
template <typename T, int N>
class StaticList :public SeqList<T>
{
protected:
T m_space[N];//顺序表存储空间
public:
StaticList()//指定父类成员值
{
this->m_array = m_space;
this->m_lenght = 0;
}
int capacity() const
{
return N;
}
};
}
#endif // !__STATICLIST_H
测试main.cpp
#include <iostream>
//#include "SmartPointer.h"
//#include"Exception.h"
//#include"Object.h"
#include "StaticList.h"
using namespace std;
using namespace DTLib;
int main()
{
StaticList<int, 5> l;
for (int i = 0; i < l.capacity(); i++)
{
l.insert(0, i);
}
for (int i = 0; i < l.lenght(); i++)
{
cout << l[i] << endl;
}
for (int i = 0; i < l.lenght(); i++)
{
cout << l[i] << endl;
}
try
{
l[5] = 5;
}
catch (const Exception& e)
{
cout << e.message() << endl;
cout << e.location() << endl;
}
return 0;
}
异常测试:越界
打印异常信息,位置
静态DynamLlist
DynamicList .h
#ifndef __DYNAMIClIST_H
#define __DYNAMIClIST_H
#include "SeqList.h"
#include "Exception.h"
namespace DTLib {
template <typename T>
class DynamicList :public SeqList<T>
{
protected:
int m_capacity;//顺序存储空间大小
public:
DynamicList(int capacity)//申请空间
{
this->m_array = new T[capacity];
if (this->m_array != NULL)
{
this->m_length = 0;
this->m_capacity = capacity;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create Dynamiclist object...");
}
}
int capacity() const
{
return m_capacity;
}
//重新设置顺序存储空间大小
void resize(int capacity)
{
if (m_capacity != capacity)
{
T* array = new T[capacity];
if (array != NULL)
{
int length = (this->m_length < capacity ? this->m_length : capacity);
for (int i = 0; i < length; i++)
{
array[i] = this->m_array[i];
}
T* temp = this->m_array;
this->m_array = array;
this->m_length = length;
this->m_capacity = capacity;
delete[] temp;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No memory to resize DynameicList object...");
}
}
}
~DynamicList()//归还空间
{
delete[] this->m_array;
}
};
}
#endif // !__DYNAMIClIST_H
测试main.cpp
#include <iostream>
//#include "SmartPointer.h"
//#include"Exception.h"
//#include"Object.h"
//#include "StaticList.h"
#include "DynamicList.h"
using namespace std;
using namespace DTLib;
int main()
{
DynamicList<int> l(5);
for (int i = 0; i < l.capacity(); i++)
{
l.insert(0, i);
}
for (int i = 0; i < l.length(); i++)
{
cout << l[i] << endl;
}
for (int i = 0; i < l.length(); i++)
{
cout << l[i] << endl;
}
try
{
l[5] = 5;//越界
}
catch (const Exception& e)
{
cout << e.message() << endl;
cout << e.location() << endl;
l.resize(10);
l.insert(5, 50);
}
for (int i = 0; i < l.length(); i++)
{
cout << l[i] << endl;
}
l.resize(3);
for (int i = 0; i < l.length(); i++)
{
cout << l[i] << endl;
}
return 0;
}
下面的代码正确吗?
d1 和d2同时指向一片堆空间,析构时释放同一片空间产生异常
解决方案
改进List.h
.......
class List :public Object
{
protected:
//改进
保护模式下,禁用拷贝构造和赋值操作
List(const List&);
List& operator= (const List&);
public:
..........
}
编译出错
需要手动添加构造函数
#ifndef __LIST_H
#define __LIST_H
#include "Object.h"
namespace DTLib {
template <typename T>
class List :public Object
{
protected:
//保护模式,禁用拷贝构造和赋值操作
List(const List&);//编译器不会默认提供构造函数
List& operator= (const List&);
public:
List() { };//所以需要手动添加构造函数
//重载,在尾部插入一个元素
virtual bool insert(const T& e) = 0;
virtual bool insert(int i, const T& e) = 0;
virtual bool remove(int i) = 0;
virtual bool set(int i, const T& e) = 0;
virtual bool get(int i, T& e) const = 0;
virtual int length() const = 0;
virtual void clear() = 0;
};
}
#endif // !__List_H
测试main.cpp
jj