2.顺序存储线性表(14-18)

这篇博客介绍了使用C++实现线性表的静态和动态存储结构,包括SeqList和StaticList、DynamicList类的定义。内容涵盖插入、删除、设置元素等基本操作,并通过异常处理确保了数组访问的安全性。此外,讨论了防止拷贝构造和赋值操作导致的问题及其解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 线性表常规的一些常用操作

狄泰软件数据结构笔记

结构层次 

线性表存储结构抽象实现(静态)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值