C++数据结构-线性表顺序存储结构设计

版权声明:QQ:763905926 未经允许请勿转载,转载请注明出处! https://blog.csdn.net/lms1008611/article/details/81623415

线性表的顺序存储结构:指的是用一段地址连续的存储单元一次存储线性表中的数据元素,如下:

有了以上概念,我们可以使用一维数组来实现线性表的顺序存储结构,

    存储空间:T* m_marry
    当前长度:int m_length

整个类继承于之前我们写的List类,并采用泛型编程,在这里我们把顺序表分为静态顺序表与动态顺序表,静态顺序表的存储空间是直接在栈上分配的,通过类模板来定义空间长度;动态顺序表是在堆空间上申请存储空间。所以这里我们暂且生成一个顺序表父类SeqList,把顺序表的基本操作在SeqList里边实现,后边的静态顺序表StaticList与动态顺序表DynamicList均继承自SeqList。

#ifndef __SEQLIST_H__
#define __SEQLIST_H__

#include "ExcepTion.h"
#include "List.h"

namespace MyLib
{
template <typename T>
class SeqList : public List<T>
{
protected:
    T* m_marray;
    int m_length;

public:
    bool insert(int index, const T& e)	//插入操作
    {
    	bool ret = true;
    	ret = (index >=0)&&(index <= m_length);
    	ret = ret && (m_length < capacity());

    	if (ret)
    	{
    	    for ( int i=m_length-1; i>=index; i-- )
    	    {
    	    	m_marray[i+1] = m_marray[i];
    	    }
    	    m_marray[index] = e;
    	    m_length ++;
    	}
    	else
    	{
    	    THROW_EXCEPTION(IndexOutOfBoundsException, "Out Of Bounts...");
    	}
    	return ret;
    }

    bool remove(int index)	//移除操作
    {
    	bool ret = true;
    	ret = (index >=0)&&(index < m_length);
	if (ret)
	{
	    for ( int i=index; i<m_length; i++ )
	    {
	   	m_marray[i] = m_marray[i+1];
	    }
	    m_length--;
	}
	else
	{
	    THROW_EXCEPTION(IndexOutOfBoundsException, "Out Of Bounts...");
	}
	return ret;
    }

    bool get(int index, T& e)	//获取元素
    {
    	bool ret = true;
    	ret = (index >=0)&&(index < m_length);
	if (ret)
	{
	    e = m_marray[index];
	}
	else
	{
	    THROW_EXCEPTION(IndexOutOfBoundsException, "Out Of Bounts...");
	}
    }

    bool set(int index, const T& e)const	//设置元素
    {
    	bool ret = true;
    	ret = (index >=0)&&(index < m_length);

    	if (ret)
    	{
    	    m_marray[index] = e;
    	}
    	else
    	{
    	    THROW_EXCEPTION(IndexOutOfBoundsException, "Out Of Bounts...");
    	}
    }

    int find(const T& e)
    {
	 int ret = -1;
	 for (int i=0; i<m_length; i++)
	 {
            if (e == m_array[i])
	    {
		ret = i;
		break;
	    }
	 }
	 return ret;
    }

    T& operator[](int index)	//数组操作符重载
    {
    	bool ret = true;
    	ret = (index >=0)&&(index < m_length);

    	if (ret)
    	{
    	    return m_marray[index];
    	}
    	else
    	{
    	    THROW_EXCEPTION(IndexOutOfBoundsException, "Out Of Bounts...");
    	}
    }

    int length()const	//获取长度
    {
    	return m_length;
    }

    void clear()	//清除线性表
    {
    	m_length = 0;
    }

    virtual int capacity() = 0;
};
}
#endif //__SEQLIST_H__

从SeqList类我们看到,除了将继承自List类的基本操作接口实现之外,我们还增加了一个纯虚函数 capacity(),所以SeqList类还bu能直接使用,这样做的目的就是为了区分静态顺序表StaticList与动态顺序表DynamicList,二者的存储结构空间一个在栈上一个在堆上。
下边先来看StaticList,它继承于SeqList

#ifndef  __STATICLIST_H__
#define	 __STATICLIST_H__

#include "SeqList.h"

namespace MyLib
{
template <typename T, int N>
class StaticList : public SeqList<T>
{
private:
    T marray[N];    //栈上定义一个数组,元素个数由类模板参数N确定
public:
    StaticList()
    {
    	m_marray = marray;    //将顺序表的地址指向定义的数组
    	m_lenght = 0;
    }

    int capacity()
    {
    	return N;    //顺序表的容量同样等于类模板的参数N
    }
};

}
#endif	//__STATICLIST_H__

自此,一个完整的StatList就实现完成了,现在来实现DynamicList,

#ifndef __DYNAMICLIST_H__
#define __DYNAMICLIST_H__

#include "SeqList.h"

namespace MyLib
{
template <typename T>
class DynamicList : public SeqList<T>
{
private:
    int m_capacity;

public:
    DynamicList(int capacity)
    {
	m_marray = new T[capacity];
	if (NULL != m_marray)
	{
	    m_capacity = capacity;
	    m_length = 0;
	}
	else
	{
	    THROW_EXCEPTION(NoEnoughtMemoryException, "No Enough Memory To Create DynamicList object...");
	}	
    }

    int capacity()
    {
	return m_capacity;
    }

    void resize(int capacity)	//重置线性表空间大小
    {
	if (capacity != m_capacity)
	{
	    int length = (m_length < capacity? m_length : capacity);

	    T *array = new T[length];
	    if (NULL != array)
	    {
		for (int i=0; i<length; i++)
		{
		    array[i] = m_marray[i];
		}
		T* temp = m_marray;
		m_marray = array;
		m_length = length;
		m_capacity = capacity;

		delete[] temp;
	    }
	    else
	    {
		THROW_EXCEPTION(NoEnoughtMemoryException, "No Enough Memory To Resize DynamicList object...")
	    }
	}
    }

    ~DynamicList()
    {
	if (NULL != m_marray)
	{
	    delete[] m_marray;
	}
    }
};

}
#endif //__DYNAMICLIST_H__

这样,我们将StaticList与DynamicList都 实现完了,现在我们在main函数中使用一下

#include <iostream>
#include <string>
#include "ExcepTion.h"
#include "StaticList.h"
#include "DynamicList.h"

using namespace std;
using namespace MyLib;

int main()
{
    StaticList<int, 5> list1;	//使用StaticList线性表
    for (int i=0; i<list1.capacity(); i++)
    {
    	list1.insert(i, i);
    }

    for (int i=0; i<list1.length(); i++)
    {
    	cout << list1[i] << endl;
    }

    cout << "******************************" << endl;
    DynamicList<int> list2(10);		//使用DynamicList线性表
    for (int i=0; i<list2.capacity(); i++)
    {
    	list2.insert(i, i);
    }
    list2.resize(8);	//重置顺序表空间
    for (int i=0; i<list2.length(); i++)
    {
    	cout << list2[i] << endl;
    }

    system("pause");

    return 0;
}

编译输出:

更多的测试可以自行验证

猜你喜欢

转载自blog.csdn.net/lms1008611/article/details/81623415
今日推荐