数据结构与算法——c++实现(刷题前必会基础)
基本操作就是遍历 + 访问(增删查改)。学习方法是手敲整理出各大数据结构必会的增删查改操作!!!
线性表
线性表顺序表示(SeqList)
- 增:(判断条件)是否超过最大容量;下标参数是否1~length范围内;(长度)更新增加后的长度;(操作)操作身边后操作自身;
- 删:(判断条件)下标参数是否1~length范围内;(长度)更新删除后的长度;(操作)操作自身后操作身边;
- 查:(根据下标查-判断条件)下标参数是否1~length范围内;(根据值查-循环条件)遍历顺序表,满足条件直接返回,未找到遍历到末尾再返回,两种完成循环的方式;
- 改:(判断条件)下标参数是否1~length范围内;
类模板定义
SeqList 增删查改
。
//SeqList
template <class ElemType>
class SeqList
{
protected:
int length;//当前SeqList长度
int maxlength;//SeqList最大容量
ElemType *elems;//SeqList的元素
public:
//增删改查
//初始表内存、初始化表内容
SeqList(int size=DEFAULT_SIZE);
SeqList(ElemType v[], int n, int size=DEFAULT_SIZE);
//析构
virtual ~SeqList();
//遍历
void Traverse(void (*Visit)(const ElemType &)) const;
//查_元素值_返回下标
int LocateElem(const ElemType &e);
//查_元素下标int i
Status GetElem(int i, ElemType &e) const;
//改_元素下标
Status SetElem(int i, ElemType &e);
//删_元素下标
Status DeleteElem(int i, ElemType &e);
//增_元素下标
Status InsertElem(int i, const ElemType &e);//有无const???
//增_表尾
Status InsertElem(const ElemType &e);
//附加
int GetLength() const;//长度
bool Isempty() const;//判断是否为空
void Clear();//清空
SeqList(const SeqList<ElemType> &sa);//复制构造函数
SeqList<ElemType> &operator = (const SeqList<ElemType> &sa);//赋值语句重载
};
//构造函数
template <class ElemType>
SeqList<ElemType>::SeqList(ElemType v[], int n, int size)
{
//三个数据成员初始化赋值
elems = new ElemType[size];
assert(elems);
maxlength = size;
length = n;
for(int i=0; i < length; i++)
elems[i] = v[i];
}
//析构函数
template <class ElemType>
SeqList<ElemType>::~SeqList()
{
delete []elems;
}
//三个数据成员都可访问
//遍历
template <class ElemType>
void SeqList<ElemType>::Traverse(void (*Visit)(const ElemType &)) const
{
for(int i=0; i<length; i++)
(*Visit)(elems[i]);
}
顺序表实现增删改查
查_元素值_返回下标(有没有)
template <class ElemType>
int SeqList<ElemType>::LocateElem(const ElemType &e) const
{
int i=0;
while(i < length && elems[i]!=e)//循环截止条件_先操作再判断是否超范围
i++;
return i<length ? i+1 :0;
}
查_元素下标
template <class ElemType>
Status SeqList<ElemType>::GetElem(int i, ElemType &e) const
{
if(i < 1 || i > length)//边界判断条件_先判断是否超范围再操作
return NOT_PRESENT;
else {
e = elems[i-1];
return ENTRY_FOUND;
}
}
改_元素下标
template <class ElemType>
Status SeqList<ElemType>::SetElem(int i, const ElemType &e)
{
if(i < 1 || i > length)//边界判断条件_先判断是否超范围再操作
return RANGE_ERROR;
else {
elems[i-1] = e;
return SUCCESS;
}
}
删_元素下标_自身+身边两部分
template <class ElemType>
Status SeqList<ElemType>::DeleteElem(int i, ElemType &e)
{
if(i < 1 || i > length)//边界判断条件_先判断是否超范围再操作
return RANGE_ERROR;
else {
e = elems[i-1];
for(int j=i; j<length; j++)
elems[j-1] = elems[j];
length--;
return SUCCESS;
}
}
增_元素下标
template <class ElemType>
Status SeqList<ElemType>::InsertElem(int i, const ElemType &e)
{
if(length == maxlength)//边界判断条件_最大容量
return OVER_FLOW;
else if(i < 1 || i > length)//边界判断条件_先判断是否超范围再操作
return RANGE_ERROR;
else {
for(int j=length; j >=i; j--)
elems[j] = elems[j-1];
elems[i-1] = e;
length++;
return SUCCESS;
}
}
线性表链式表示
单链表
重点!!!p是第i个结点,q是第i+1个结点
- 增(在第i个位置之前添):(判断条件)下标参数是否1~length范围内;(长度)更新增加后的长度;(操作)操作自身后操作身边;第一步是操作自身:
q = new Node<ElemType>(e, p->next)
,第二步是操作其它:p->next = q
- 删:(判断条件)下标参数是否1~length范围内;(长度)更新删除后的长度;(操作)操作身边后操作自身;第一步是操作身边:
q = p->next
,p->next = q ->next
,第二步是操作自身,delete q
; - 查:(根据下标查-判断条件)下标参数是否1~length范围内;(根据值查-循环条件)遍历顺序表,满足条件直接返回,未找到遍历到末尾再返回,两种完成循环的方式
while(*p!=NULL && p->data != e)
; - 改:(判断条件)下标参数是否1~length范围内;
单链表结点类模板的定义和实现(链表结构体)
template <class ElemType>
struct Node
{
ElemType data;
Node<ElemType> *next;
//构造函数
Node();
Node(ElemType e, Node<ElemType> *link=NULL);
};
//无参数的构造函数(头结点)
template <class ElemType>
Node<ElemType>::Node()
{
next = NULL;
}
//有参数的构造函数
template <class ElemType>
Node<ElemType>::Node(ElemType e, Node<ElemType> *link)
{
data = e;
next = link;
}
template <class ElemType>
class LinkList
{
protected:
Node<ElemType> *head;
int length;
public:
//增删改查
//初始表内存、初始化表内容
LinkList();
LinkList(ElemType v[], int n);
//析构
virtual ~LinkList();
//清空
void Clear();
//遍历
void Traverse(void (*Visit)(const ElemType &)) const;
//查_元素值_返回下标
int LocateElem(const ElemType &e);
//查_元素下标int i
Status GetElem(int i, ElemType &e) const;
//改_元素下标
Status SetElem(int i, ElemType &e);
//删_元素下标
Status DeleteElem(int i, ElemType &e);
//增_元素下标
Status Insert(int i, const ElemType &e);//有无const???
//增_表尾
Status InsertElem(const ElemType &e);
//附加
int GetLength() const;//长度
bool Isempty() const;//判断是否为空
LinkList(const LinkList<ElemType> &sa);//复制构造函数
LinkList<ElemType> &operator = (const LinkList<ElemType> &sa);//赋值语句重载
};
//有参构造函数
template <class ElemType>
LinkList<ElemType>::LinkList(ElemType v[], int n)
{
//初始化链表=构造头结点+初始化各个节点
Node<ElemType> *p;
p = head = new Node<ElemType>;//构造头结点
assert(head);
for(int i=0; i<n; i++)
{
//p和next都存储地址,p是当前节点地址,next是下一节点地址
p->next = new Node<ElemType>(v[i], NULL);//新建节点地址赋给上一节点指针域
assert(p->next);
p = p->next;//相当于i++,向后移动一个节点
}
length = n;
}
//析构函数
template <class ElemType>
LinkList<ElemType>::~LinkList()
{
Clear();
delete head;//这就可以了吗???
}
//清空
template <class ElemType>
void LinkList<ElemType>::Clear()
{
Node<ElemType> *p=head->next;
while(p!=NULL)</