目录
如果觉得我写得还行的话,希望三连,鼓励一下哦!!!
1.线性表的定义
一个线性表是n个相同类型的数据元素的有限序列。
2.线性表的逻辑特征
(1)有且仅有一个开始结点(无前趋);
(2)有且仅有一个终端结点(无后继);
(3)其余结点ai都有且仅有一个前趋和一个后继
;
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)存储分配只能预先进行(静态) 过大 浪费 过小
溢出
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();
}