您的位置:首页 > 理论基础 > 数据结构算法

数据结构——简单线性表(顺序存储)

2017-03-30 16:22 381 查看
线性表的顺序存储结构指的是用一段地址连续的存储单元依次存储线性表的数据元素,譬如STL中的vector和array。STL已经封装好了基本的数据结构,我们只需直接调用即可,如果我们想实现相同功能的数据结构,可以对照STL中容器相关的结构来编写代码。

下面是最简单的顺序存储结构线性表:

SqList.h

/*   顺序表:类似于STL中的vector和array   */

const int DefaultSize = 100;	//默认顺序表规模,只读

template<typename Type>class SqList
{
private:
Type *m_elements;		//元素指针
const int m_maxsize;	//最大规模,只读
int m_currentsize;		//当前规模

public:
//构造函数:为数据成员分配空间
SqList(int sz = DefaultSize) :m_maxsize(sz), m_currentsize(-1)
{
if (sz > 0)
{
m_elements = new Type[m_maxsize];
}
}
//析构函数:释放数据成员指针所指内存
~SqList()
{
delete[] m_elements;
}
//获顺序表取当前规模
int Length()
{
return m_currentsize + 1;
}
//常成员函数,只能引用不能修改数据成员
int Find(Type x) const;			//返回元素x的第一个位置
int IsElement(Type x) const;	//判断x是否为顺序表中元素

int Insert(Type x, int pos);	//在位置pos处插入元素x
int Remove(Type x);				//删除元素x
int IsEmpty()					//判断顺序表是否为空
{
return m_currentsize == -1;
}
int IsFull()					//判断顺序表是否已满
{
return m_currentsize == m_maxsize - 1;
}
Type Get(int ith)					//获取位置i的元素
{
//逗号表达式(从左到右执行,返回最右边的值),输出错误信息并返回0
return ith<0 || ith>m_maxsize ? (cout << "无法获取该元素!" << endl, 0) : m_elements[ith];
//if (ith<0 || ith>m_maxsize)
//{
//	cout << "无法获取该元素!" << endl;
//	return 0;
//}
//return m_elements[ith];
}

void Print();						//打印顺序表内所有元素

SqList<Type>& operator = (const SqList<Type> &sql);   //赋值运算符重载
Type operator [] (int ith);   //[]下标运算符重载
};
/* 查找操作,查找成功返回该元素第一次出现的位置,否则返回-1
*
*/
template<typename Type> int SqList<Type>::Find(Type x) const
{
for (int i = 0; i <= m_currentsize; i++)
{
if (x == m_elements[i])
return i+1;
}
cout << "该元素不在该顺序表中!" << endl;
return -1;
}
/* 判断顺序表中元素x是否存在,存在返回1,不存在返回0
*  直接调用Find()方法
*/
template<typename Type> int SqList<Type>::IsElement(Type x) const
{
if (Find(x) == -1)
return 0;
return 1;
}
/* 插入操作,插入成功返回1,插入失败返回0
*  首先对插入元素的位置进行合法性判断,并判断顺序表是否已满
*  再将插入位置pos后的元素全部向后移一位
*/
template<typename Type>int SqList<Type>::Insert(Type x, int pos)
{
if (pos<0||pos>m_currentsize+1||m_currentsize == m_maxsize-1)
{
cout << "插入操作不合法!" << endl;
return 0;
}
m_currentsize++;
for (int j = m_currentsize; j > pos; j--)
{
m_elements[j] = m_elements[j - 1];
}
m_elements[pos] = x;
return 1;
}
/* 删除操作,删除成功返回1,删除失败返回0
*  首先记录下顺序表当前规模,每次遍历到欲删除元素后将其后所有元素前移一位,并更新当前规模(-1)
*  每次循环至少保证当前规模-1或索引值+1,直至删除顺序表中所有元素x
*/
template<typename Type>int SqList<Type>::Remove(Type x)
{
int size = m_currentsize;
for (int i = 0; i < m_currentsize;)
{
if (x == m_elements[i])
{
for (int j = i; j < m_currentsize; j++)
{
m_elements[j] = m_elements[j + 1];
}
m_currentsize--;
continue;
}
i++;
}
if (size == m_currentsize)
{
cout << "未找到欲删除的元素!" << endl;
return 0;
}
return 1;
}
/* 打印顺序表中所有元素
*/
template<typename Type>void SqList<Type>::Print()
{
for (int i = 0; i <= m_currentsize; i++)
{
cout << i+1 << "==>" << m_elements[i] << endl;
}
cout << endl;
}

/* 赋值运算符重载
*  类含有指针数据成员需要重新分配内存给临时指针变量
*/
template<typename Type>SqList<Type>& SqList<Type>::operator = (const SqList<Type> &sql)
{
if (this != &sql)
{
this->m_currentsize = sql.m_currentsize;
//临时指针变量
Type *eTemp = new Type[sql.m_currentsize+1];
for (int i = 0; i <= sql.m_currentsize; i++)
{
eTemp[i] = sql.m_elements[i];
}
this->m_elements = eTemp;
}
return *this;
}

template<typename Type>Type SqList<Type>::operator [] (int ith)
{
return Get(ith);
}


Test.cpp

#include <iostream>
#include <string>
#include "SqList.h"
using namespace std;

int main(void)
{
SqList<string> mylist(10);
cout << mylist.IsEmpty() << endl;
mylist.Insert("hello", 0);
mylist.Insert("world", 1);
cout << mylist[1] << endl;
cout << mylist.IsFull() << endl;
cout << mylist.IsElement("HELLO") << endl;
mylist.Print();
mylist.Remove("hello");
mylist.Print();
cout << "'world'元素位置:" << mylist.Find("world") << endl;
SqList<string> templist(10);
templist = mylist;
templist.Print();

return 0;
}


测试结果:

1
world
0
该元素不在该顺序表中!
0
1==>hello
2==>world

1==>world

'world'元素位置:1
1==>world
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: