数据结构与算法设计3 顺序表和链表

目录

1.线性表的定义

2.线性表的逻辑特征

3.数据元素的特性

4.顺序表的类模板定义

5.顺序表的优缺点

6.单链表的类模板定义

7.双向循环链表的类模板定义


 如果觉得我写得还行的话,希望三连,鼓励一下哦!!! 

1.线性表的定义

一个线性表是n个相同类型的数据元素的有限序列。

2.线性表的逻辑特征

(1)有且仅有一个开始结点a_{1}(无前趋);

(2)有且仅有一个终端结点a_{n}(无后继);

(3)其余结点ai都有且仅有一个前趋a_{i-1}和一个后继a_{i+1};

3.数据元素的特性

(1)线性表中的所有数据元素的数据类型是一致的;

(2)数据元素在线性表中的位置只取决于它的序号;

(3)数据元素间的逻辑关系是线性的;

4.顺序表的类模板定义

#pragma once
#include<iostream>
#include<cstring>
#include<assert.h>
using namespace std; 
typedef enum {
    NOT_PRESENT, ENTRY_FOUND, RANGE_ERROR, SUCCESS, OVER_FLOW,DEFAULT_SIZE
}Status;
template <class ElemType>

class SeqList {
protected:
	int length;	    //顺序表的当前长度
    int maxLength;  //顺序表的最大容量
    ElemType* elems;   //元素存储空间的首地址
public:
    SeqList(int size = DEFAULT_SIZE); //构造函数
    SeqList(ElemType v[], int n, int size = DEFAULT_SIZE);
    //构造函数,跟据数组v的内容构造顺序表
    virtual ~SeqList();  //析构函数
    int GetLength() const;  //取顺序表的长度
    bool IsEmpty() const;  //判断顺序表是否为空
    void Clear();  //清空顺序表
    void Traverse(void (*visit)(const ElemType&)) const;  //遍历顺序表
    int LocateElem(const ElemType& e)const; //元素定位
    Status GetElem(int i, ElemType& e) const; //取得顺序表第i个元素的值
    Status SetElem(int i, const ElemType& e); //修改顺序表第i个元素的值
    Status DeleteElem(int i, ElemType& e); //删除顺序表第i个元素的值
    Status InsertElem(int i, const ElemType& e); //在任意位置插入
    Status InsertElem(const ElemType& e); //尾插
    SeqList(const SeqList<ElemType>& sa); //拷贝构造
    SeqList<ElemType>& operator=(const SeqList<ElemType>& sa);//赋值运算符重载
};
template <class ElemType>
//构造空顺序表
SeqList<ElemType>::SeqList(int size)
{
    elems = new ElemType[size];//申请内存空间
    assert(elems);//判断是否成功
    maxLength = size;//设置顺序表最大容量
    length = 0;//空线性表的长度为0
}
template <class ElemType>
//根据数组内容构造顺序表
SeqList<ElemType>::SeqList(ElemType v[], int n, int size) {
    elems = new ElemType[size];//申请内存空间
    assert(elems);//判断是否成功
    maxLength = size;//设置顺序表最大容量
    length = n;//线性表的长度为n
    for (int i = 0; i < length; i++)//将数组v中的元素依次存放到elems数组中
        elems[i] = v[i];
}
template <class ElemType>
//析构函数
SeqList<ElemType>::~SeqList()
{
    delete[]elems;
}

template <class ElemType>
//清空顺序表
void SeqList<ElemType>::Clear()
{
    length = 0;
}
template <class ElemType>
//遍历顺序表
void SeqList<ElemType>::Traverse(void (*visit)(const ElemType&)) const
{
    for (int i = 1; i <= length; i++)
        (*visit)(elems[i - 1]);
}
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 + 1)   return RANGE_ERROR;
    else {
        for (int j = length; j >= i; j--)  //移动元素
            elems[j] = elems[j - 1];
        elems[i - 1] = e;
        length++;
        return SUCCESS;
    }
}
template <class ElemType>
//在顺序表尾部插入数据
Status SeqList<ElemType>::InsertElem(const ElemType& e)
{
    if (this->length == this->maxLength)
        return OVER_FLOW;
    else {
        this->elems[this->length] = e;
        this->length++;
        return SUCCESS;
    }
}
//取顺序表的长度
template <class ElemType>
int SeqList<ElemType>::GetLength() const {
    return length;
}
//判断顺序表是否为空
template <class ElemType>
bool SeqList<ElemType>::IsEmpty() const {
    return length ? false : true;
}
//拷贝构造函数
template <class ElemType>
SeqList<ElemType>::SeqList(const SeqList<ElemType>& sa) {
    elems = new ElemType[sa.maxLength];
    assert(elems);
    maxLength = sa.maxLength;
    length = sa.length;
    for (int i = 0; i < length; i++)
        elems[i] = sa.elems[i];
}
//赋值运算符重载
template <class ElemType>
SeqList<ElemType>& SeqList<ElemType>::operator=(const SeqList<ElemType>& sa) {
    if (this == &sa)	return *this;
    if (elems)	delete[]elems;
    elems = new ElemType[sa.maxLength];
    assert(elems);
    maxLength = sa.maxLength;    length = sa.length;
    for (int i = 0; i < length; i++)    elems[i] = sa.elems[i];
    return *this;
}


5.顺序表的优缺点

优点: (1)无须为表示数据元素之间的逻辑关系而增加额外的存储空间。

           (2)可以方便地随机访问表中的任一数据元素。

缺点: (1)插入和删除平均须移动一半结点。

           (2)存储分配只能预先进行(静态)  过大  \rightarrow  浪费    过小  \rightarrow  溢出

6.单链表的类模板定义

 结点类的定义

#pragma once
template<class ElemType>
struct Node {
private:
	Node<ElemType>* next;
	ElemType data;
public:
	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;
}

Status枚举类型定义 

#pragma once
typedef enum{ NOT_PRESENT, ENTRY_FOUND, RANGE_ERROR, SUCCESS, OVER_FLOW }Status;
#pragma once
#include"Node.h"
#include"Status.h"
#include"assert.h"
template<class ElemType>
class LinkList {
private:
	Node <ElemType>* head;
	int length;
public:
	LinkList();
	LinkList( ElemType v[], int n);
	virtual~LinkList();
	int Getlength()const;
	bool IsEmpty();
	void clear();
	void Traverse( void(*visit)( const ElemType& ))const;
	int LocateElem(const ElemType& e);
	Status GetElem(int i, ElemType& e)const;
	Status SetElem(int i, const ElemType& e);
	Status DeletElem(int i, ElemType& e);
	Status InsertElem(int i, const ElemType& e);
	Status InsertElem(const ElemType& e);
	LinkList(const LinkList <ElemType>& ee);
	LinkList<ElemType>& operator=(const LinkList <ElemType>& ee);

};
template<class ElemType>
LinkList <ElemType>::LinkList() {
	head = new Node<ElemType>;
	length = 0;
}
template<class ElemType>
LinkList <ElemType>::LinkList(ElemType v[], int n) {
	Node <ElemType>* p;
	head = new Node <ElemType>;
	p = head;
	for (int i = 0; i < n; i++) {
		p->next = new Node<ElemType>(v[i], NULL);
		assert(p->next);
		p = p->next;
	}
	length = n;
}
template<class ElemType>
LinkList<ElemType>::~LinkList() {
	clear();
	delete head;
}
template<class ElemType>
int LinkList<ElemType>::Getlength()const {
	return length;
}
template<class ElemType>
bool LinkList<ElemType>::IsEmpty() {
	return length ? false : true;
}
template<class ElemType>
void LinkList<ElemType>::clear() {
	Node <ElemType>* p = head->next;
	while (p != NULL) {
		head->next = p->next;
		delete p;
		p = head->next;
	}
	length = 0;
}
template<class ElemType>
void LinkList<ElemType>::Traverse(void(*visit)(const ElemType&))const {
	Node<ElemType>* p = head->next;
	while (p!=NULL)
	{
		(*visit)(p->data);
		p = p->next;
	}


}
template<class ElemType>
int LinkList<ElemType>::LocateElem(const ElemType& e) {
	int count = 1;
	Node<ElemType>* p = head->next;
	while (p!=NUll &&p->data!=e)
	{
		p = p->next;
		count++;
	}
	return  p != NUll ? count : 0;
}
template<class ElemType>
Status LinkList<ElemType>::GetElem(int i, ElemType& e)const {
	if (i<1 || i>length) {
		return RANGE_ERROR;
	}
	else {
		Node<ElemType>* p = head->next;
		for (int count = 1; count < i; count++) {
			p = p->next;

		}
		e = p->data;



		return ENTRY_FOUND;
	}
}
template<class ElemType>
Status  LinkList<ElemType>::SetElem(int i, const ElemType& e) {
	if (i<1 || i>length) {
		return RANGE_ERROR;
	}
	else
	{
		Node<ElemType>* p = head->next;
		for (int count = 1; count < i; count++) {
			p = p->next;
		}
		p->data = e;
	}
	return SUCCESS;
}
template<class ElemType>
Status LinkList<ElemType>::DeletElem(int i, ElemType& e){
	if (i<1 || i>length) {
		return RANGE_ERROR;
	}
	else {
		Node<ElemType>* p = head, * q;
		for (int count = 1; count < i; i++) 
		p = p->next; 
		q = p->next;
		p->next = q->next;
		e = q->data;
		length--;
		delete q;
		return SUCCESS;
	}
}
template<class ElemType>
Status LinkList<ElemType>::InsertElem(int i, const ElemType& e){
	if (i<1 || i>length+1) {
		return RANGE_ERROR;
	}
	else {
		Node<ElemType>* p = head, q;
		for (int count = 1; count < i; i++) {
			p = p->next;
		}
		q = new Node<ElemType>(e, p->next);
		
		p->next = q;
		length++;
		return SUCCESS;
	}
}
template<class ElemType>
Status LinkList<ElemType>::InsertElem(const ElemType& e){
	
		if (i<1 || i>length + 1) {
			return RANGE_ERROR;
		}
		else {
			Node<ElemType>* p, q;
			q = new Node <ElemType>(e, NULL);
			for (p = head; p->next!= NULL; p = p->next) 
			p->next = q;
			length++;
			return SUCCESS;
		}

}
template<class ElemType>
LinkList<ElemType>::LinkList(const LinkList <ElemType>& ee){
	head = new Node<ElemType>; 
	assert(head);
	ElemType temp;
	for (int i = 1; i <= Getlength(); i++) {
		ee.GetElem(i, temp);
		InsertElem(i, temp);
	}
	length = ee.Getlength();
}
template<class ElemType>
LinkList<ElemType>& LinkList<ElemType>::operator=(const LinkList <ElemType>& ee){
	head = new Node<ElemType>;
	assert(head);
	if (this == &ee)	
		return *this;
	if (head != NULL) {
		delete head;
	}
	ElemType temp;
	for (int i = 1; i <= Getlength(); i++) {
		ee.GetElem(i, temp);
		InsertElem(i, temp);
	}
	length = ee.Getlength();
}

7.双向循环链表的类模板定义

结点类的定义 

#pragma once
template<class ElemType>
struct DblNode
{
private:
	DblNode<ElemType>* next;
	DblNode<ElemType>* prior;
	ElemType data;
public:
	DblNode();
	DblNode(ElemType e, DblNode<ElemType>* linkprior, DblNode<ElemType>* linknext  );
};
template<class ElemType>
DblNode<ElemType>::DblNode() {
	next = NULL;
	prior = NULL;
}
template<class ElemType>
DblNode<ElemType>::DblNode(ElemType e, DblNode<ElemType>* linkprior, DblNode<ElemType>* linknext) {
	data = e;
	prior = linkprior;
	next = linknext;
}

 枚举类型Status的定义

#pragma once
typedef enum{ NOT_PRESENT, ENTRY_FOUND, RANGE_ERROR, SUCCESS, OVER_FLOW }Status;
#pragma once
#include"DblNode.h"
#include"Status.h"
#include"assert.h"
template <class ElemType >
class DblLinkList
{
private:
	int length;
	DblNode<ElemType>* head;
public:
	DblLinkList();
	DblLinkList(ElemType v[], int n);
	virtual~DblLinkList();
	int Getlength()const;
	bool IsEmpty()const;
	void Clear();
	int LocateElem(const ElemType& e);
	void Traverse(void(*visit)(const ElemType &))const;
	Status GetElem(int i, ElemType& e)const;
	Status SetElem(int i, const ElemType& e);
	Status DeletElem(int i, ElemType& e);
	Status InsertElem(int i, const ElemType& e);
	Status InsertElem(const ElemType& e);
	DblLinkList(const ElemType& sa);
	DblLinkList<ElemType>& operator=(const DblLinkList<ElemType>& sa);
}; 
template <class ElemType >
DblLinkList<ElemType>::DblLinkList() {
	head = new DblNode<ElemType>;
	head->next = head;
	head->prior =head;
	length = 0;
}
template <class ElemType >
DblLinkList<ElemType>::DblLinkList(ElemType v[], int n) {
	DblNode<ElemType>* p;
	p = head = new DblNode<ElemType>;
	for (int i = 0; i < n; i++) {
		p->next = new DblNode<ElemType>(v[i], p);
		p = p->next;
	}
	length = n;
	head->prior = p;
	p->next = head;
}
template <class ElemType >
DblLinkList<ElemType>::~DblLinkList() {
	Clear();
	delete head;
}
template <class ElemType >
int DblLinkList<ElemType>::Getlength()const {
	return length;

}
template <class ElemType >
bool DblLinkList<ElemType>::IsEmpty()const{
	return (length == 0);
}
template <class ElemType >
void DblLinkList<ElemType>::Clear() {
	ElemType a;
	while (length>0)
	{
		DeletElem(1, a);
	}
}
template <class ElemType >
int DblLinkList<ElemType>::LocateElem(const ElemType& e) {
	DblNode<ElemType>* p = head->next;
	int count = 1;
	while (p!=head && p->data!= e)
	{
		count++;
		p = p->next;
	}
	if (p != head)
		return count;
	else
	{
		return 0;
	}
}
template <class ElemType >
void DblLinkList<ElemType>::Traverse(void(*visit)(const ElemType&))const {
	DblNode<ElemType>* p;
	for (p = head->next; p != head; p = p->next) {
		(*visit)(p->data);
	}
}
template <class ElemType >
Status DblLinkList<ElemType>::GetElem(int i, ElemType& e)const{
	DblNode<ElemType>* p = head->next;
	int count;
	if (i<1 || i> length) {
		return NOT_PRESENT;
	}
	else
	{
		for (count = 1; count < i; count++) {
			p = p->next;
			e = p->data;
		}
		return ENTRY_FOUND;
	}
}
template <class ElemType >
Status DblLinkList<ElemType>::SetElem(int i, const ElemType& e) {
	DblNode<ElemType>* p = head->next;
	int count;
	if (i<1 || i> length) {
		return NOT_PRESENT;
	}
	else
	{
		for (count = 1; count < i; count++) {
			p = p->next;
			p->data = e;
		}
		return ENTRY_FOUND;
	}
}

template <class ElemType >
Status DblLinkList<ElemType>::DeletElem(int i, ElemType& e) {
	DblNode<ElemType>* p = head->next;
	int count;
	if (i<1 || i> length) {
		return NOT_PRESENT;
	}
	for (count = 1; count < i; count++) {
		p = p->next;	
	}
	p->prior->next = p->next;
	p->next->prior = p->prior;
	e = p->data;
	length--;
	delete p;
	return SUCCESS;
}
template <class ElemType >
Status DblLinkList<ElemType>::InsertElem(int i, const ElemType& e) {
	DblNode<ElemType>* p = head->next, * q;
	int count;
	if (i<1 || i> length) {
		return NOT_PRESENT;
	}
	else {
		for (count = 1; count < i; count++) {
			p = p->next;
		}
		q = new DblNode<ElemType>(e, p->prior, p);
		p->prior->next = q;
		p->prior = q;
		length++;
		return SUCCESS;
	}
}
template <class ElemType >
Status DblLinkList<ElemType>::InsertElem(const ElemType& e) {
	DblNode<ElemType>* p;
	p = new DblNode<ElemType>(e, head->prior, head);
	head->prior->next = p;
	head->prior = p;
	length++;
	return SUCCESS;
}
template <class ElemType >
DblLinkList<ElemType>::DblLinkList(const ElemType& ee) {
	head = new Node<ElemType>;
	assert(head);
	ElemType temp;
	for (int i = 1; i <= Getlength(); i++) {
		ee.GetElem(i, temp);
		InsertElem(i, temp);
	}
	length = ee.Getlength();
}
template <class ElemType >
DblLinkList<ElemType>& DblLinkList<ElemType>::operator=(const DblLinkList<ElemType>& ee) {
	head = new Node<ElemType>;
	assert(head);
	if (this == &ee)
		return *this;
	if (head != NULL) {
		delete head;
	}
	ElemType temp;
	for (int i = 1; i <= Getlength(); i++) {
		ee.GetElem(i, temp);
		InsertElem(i, temp);
	}
	length = ee.Getlength();
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小学生!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值