数据结构引言
你好!这是笔者在学校学习数据结构时候的类似与笔记抑或是学习记录的一系列博文,一般在每个周末的晚上更新,希望可以对你有所帮助也同时是监督自己认真学习的一种办法。如果文章中有出现任何的错误尽情指正。本学校的教材为《数据结构与算法》(c++版,清华大学出版社),所有功能均由c++实现
线性表
线性表是由类型相同的元素数据组成的有限序列,不同线性表的数据元素类型可以是不同的,在一些复杂的线性表中通常数据是有若干元素组成的,这个时候一般把数据元素称为记录,线性表有两种实现方式一种是顺序表一种是链表。
顺序表链表的区别在于在无力地址中是不是连续的,顺序表储存在一串连续的物理地址中,链表则可以不连续
顺序表
基本概念
一个简单的线性表可以表示为:
(a1,a2,…,ai,ai+1…,an)
其中ai领先于ai+1,则ai称为ai+1的直接前驱,简称前驱,ai+1称为ai的直接后继,简称后继。
线性表的类模板以及各种功能的实现
template <class ElemType>
class SqList
{
protected:
int count; // 元素个数
int maxSize; // 顺序表最大元素个数
ElemType *elems;
public:
SqList(int size = 10); // 构造函数模板
virtual ~SqList(); // 析构函数模板
int Length() const; // 求线性表长度
bool Empty() const; // 判断线性表是否为空
void Clear(); // 将线性表清空
void Traverse(void(* visit)(const ElemType &))const;
bool GetElem(int position, ElemType &e) const; // 求指定位置的元素
bool SetElem(int position, const ElemType &e); // 设置指定位置的元素值
bool Insert(int position, const ElemType &e); // 插入元素
};
在主函数中创建顺序表
SqList<int> l1;
具体功能
template <class ElemType>
SqList<ElemType>::SqList(int size)
//构造一个最大元素为size的空顺序表
{
maxSize=size;
elems = new ElemType[maxSize];
count=0;
}
template <class ElemType>
SqList<ElemType>::~SqList()
{
delete []elems; // 释放存储空间
}
template <class ElemType>
int SqList<ElemType>::Length()const
//求线性表长度
{
return count;
}
template <class ElemType>
bool SqList<ElemType>::Empty()const
//判断线性表是否为空
{
return count==0;
}
template <class ElemType>
void SqList<ElemType>::Clear()
//清空线性表
{
count=0;
}
template <class ElemType>
void SqList<ElemType>::Traverse(void(* visit)(const ElemType &))const
//遍历线性表并依次调用
{
for(int pos=1;pos<=Length();pos++)
{
(*visit)(elems[pos-1]);
}
}
template <class ElemType>
bool SqList<ElemType>::GetElem(int position, ElemType &e)const
//当线性表存在第position个元素,用e返回其值,返回ture
//否则返回false
{
if(position<1||position>Length())
return false;
else
{
e=elems[position-1];
return true;
}
}
template <class ElemType>
bool SqList<ElemType>::SetElem(int position, const ElemType &e)
//将线性表的第position个位置的元素赋值为额,
//position的取值位置为1<=position<=length()
{
if(position<1||position>Length())
return false;
else
{
elems[position-1]=e;
return true;
}
}
两个比较重要的功能
插入
这里先给出代码
template <class ElemType>
bool SqList<ElemType>::Insert(int position, const ElemType &e)
//插入值
{
ElemType tmp;
if (count == maxSize)
{ return false; }
else if (position<1 || position>Length()+1)
{ return false; }
else
{
for (int pos = Length(); pos>=position;pos--)//此处要将最后一个位置向前移,因为由逆序所以要从最后一个元素开始操作
{
elems[pos]=elems[pos-1];//赋值操作
}
elems[position-1]=e;
count++;
return true;
}
}
a1 | a2 | … | ai | ai+1 | … | an |
---|---|---|---|---|---|---|
a1 | a2 | … | e | ai | ai+1 | … |
此图为物理地址上的示意,顺序表是个连续的存储结构所以要插入一个值的时候要对其之后的元素全部作出改动,所以先将插入位置之后的先往后移动。
删除操作
template <class ElemType>
bool SqList<ElemType>::Delete(int position,ElemType &e)
//删除元素
{
ElemType tmp;
if(position<1 || position>Length())//判断位置是否合理
{
return false;
}
else
{
GetElem(position,e);//取出要删除的值
for(int pos=position+1;pos<=Length();pos++)//这里要从position位置向后移动
{
GetElem(pos,tmp);SetElem(pos-1.tmp);//将后一个的值赋给前一个
}
count--;
return true;
}
}
删除操作于插入操作相类似,只是要把元素向前移动。所以要从
a1 | a2 | … | e | ai | ai+1 | … |
---|---|---|---|---|---|---|
a1 | a2 | … | ai | ai+1 | … | an |
插入和删除算法的时间复杂度计算
挖坑
链表
挖坑