1. 线性表抽象类
#pragma once
template <class T>
class LinearList
{
public:
// 线性表是否为空
virtual bool empty() const = 0;
// 线性表大小
virtual int size() const = 0;
// 根据ID获取线性表元素
virtual T& get(int theIndex) const = 0;
// 根据元素获取元素对应ID
virtual int indexOf(const T& theElement) const = 0;
// 删除ID处的元素
virtual void erase(int theIndex) = 0;
// 在ID处插入元素
virtual void insert(int theIndex, const T& theElement) = 0;
// 输出线性表
virtual void output() = 0;
};
2. 线性表的数组描述
#include"linearList.h"
#include<iostream>
using namespace std;
template<class T>
class ArrayList :public LinearList<T>
{
protected:
T* element; // 线性表元素指针
int arrayLength; // 容量
int listSize; // 元素个数
bool checkIndex(int theIndex) const; // 检查索引是否有效
void changeLength(); // 扩充数组长度
public:
// 构造函数
ArrayList(int initialCapacity = 10);
// 拷贝构造函数
ArrayList(const ArrayList<T>& theList);
// 析构函数
~ArrayList()
{
delete[] element;
}
// 线性表是否为空
bool empty() const { return listSize == 0; }
// 线性表大小
int size() const { return listSize; }
// 线性表容量
int capacity() const { return arrayLength; }
// 根据ID获取线性表元素
T& get(int theIndex) const;
// 根据元素获取元素对应ID
int indexOf(const T& theElement) const;
// 删除ID处的元素
void erase(int theIndex);
// 在ID处插入元素
void insert(int theIndex, const T& theElement);
// 输出线性表
void output();
};
// 构造函数
template<class T>
ArrayList<T>::ArrayList(int initialCapacity)
{
if (initialCapacity < 1)
{
cout << "初始化容量必须大于0" << endl;
return;
}
this->arrayLength = initialCapacity;
this->element = new T[arrayLength];
listSize = 0;
}
// 复制构造函数
template<class T>
ArrayList<T>::ArrayList(const ArrayList<T>& theList)
{
this->arrayLength = theList.arrayLength;
this->listSize = theList.listSize;
this->element = new T[arrayLength];
copy(theList.element, theList.element + listSize, element);
}
// 越界, false 表示越界, true 表示没有越界
template<class T>
bool ArrayList<T>::checkIndex(int theIndex) const
{
bool ret = !(theIndex < 0 || theIndex > listSize);
return ret;
}
// 获取元素
template<class T>
T& ArrayList<T>::get(int theIndex) const
{
if (checkIndex(theIndex))
{
return element[theIndex];
}
}
// 根据元素获取ID
template<class T>
int ArrayList<T>::indexOf(const T& theElement) const
{
int theIndex = (int)find(element, element + listSize, theElement);
return theIndex == listSize ? -1 : (theIndex-(int)element)/sizeof(T);
}
// 删除ID处元素
template<class T>
void ArrayList<T>::erase(int theIndex)
{
if (checkIndex(theIndex))
{
copy(element + theIndex + 1, element + listSize, element + theIndex);
element[--listSize].~T();
}
}
// 扩充数组长度
template<class T>
void ArrayList<T>::changeLength()
{
T* temp = new T[arrayLength * 2];
copy(element, element + arrayLength, temp);
delete[] element;
element = temp;
arrayLength = 2 * arrayLength;
}
// 在ID处插入元素
template<class T>
void ArrayList<T>::insert(int theIndex, const T& theElement)
{
if (!checkIndex(theIndex))
{
cout << "无效索引" << endl;
return;
}
if (listSize == arrayLength)
{
changeLength();
}
copy_backward(element + theIndex, element + listSize, element + listSize + 1);
element[theIndex] = theElement;
listSize++;
}
// 输出线性表
template<class T>
void ArrayList<T>::output()
{
for (int i = 0; i < listSize; i++)
{
cout << element[i] << " ";
}
cout << endl;
}
3. 线性表的链式描述
3.1 结点结构体
#pragma once
#include<iostream>
using namespace std;
template <class T>
struct ChainNode
{
// 数据成员
T element;
ChainNode<T>* next;
// 方法
ChainNode() {}
ChainNode(const T& element)
{
this->element = element;
}
ChainNode(const T& element, ChainNode<T>* next)
{
this->element = element;
this->next = next;
}
};
3.2 线性表实现
#include"linearList.h"
#include"chianNode.h"
#include<iostream>
using namespace std;
template<class T>
class Chain :public LinearList<T>
{
protected:
ChainNode<T>* firstNode;
int listSize;
bool checkIndex(int theIndex) const;
public:
Chain(int initialCapacity = 10);
Chain(const Chain<T>&);
~Chain();
bool empty() const { return listSize == 0; };
// 线性表大小
int size() const { return listSize; }
// 根据ID获取线性表元素
T& get(int theIndex) const;
// 根据元素获取元素对应ID
int indexOf(const T& theElement) const;
// 删除ID处的元素
void erase(int theIndex);
// 在ID处插入元素
void insert(int theIndex, const T& theElement);
// 输出线性表
void output();
};
// 普通的构造函数
template<class T>
Chain<T>::Chain(int initialCapacity)
{
if (initialCapacity < 1)
{
cout << "初始容量设置必须大于0" << endl;
}
firstNode = NULL;
listSize = 0;
}
// 拷贝构造函数
template<class T>
Chain<T>::Chain(const Chain<T>& theList)
{
listSize = theList.listSize;
if (listSize == 0)
{
firstNode = NULL;
return;
}
ChainNode<T>* sourceNode = theList.firstNode;
firstNode = new ChainNode<T>(sourceNode->element);
sourceNode = sourceNode->next;
ChainNode<T>* targetNode = firstNode;
while (sourceNode != NULL)
{
targetNode->next = new ChainNode<T>(sourceNode->element);
targetNode = targetNode->next;
sourceNode = sourceNode->next;
}
targetNode->next = NULL;
}
// 析构函数
template<class T>
Chain<T>::~Chain()
{
while (firstNode != NULL)
{
ChainNode<T>* nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
template<class T>
T& Chain<T>::get(int theIndex) const
{
if (checkIndex(theIndex))
{
ChainNode<T>* currentNode = firstNode;
for (int i = 0; i < theIndex; i++)
{
currentNode = currentNode->next;
}
return currentNode->element;
}
}
template<class T>
int Chain<T>::indexOf(const T& theElement) const
{
ChainNode<T>* currentNode = firstNode;
int index = 0;
while (currentNode->element != theElement && currentNode != NULL)
{
currentNode = currentNode->next;
index++;
}
return currentNode == NULL ? -1 : index;
}
template<class T>
void Chain<T>::erase(int theIndex)
{
if (checkIndex(theIndex))
{
ChainNode<T>* deleteNode;
if (theIndex == 0)
{
deleteNode = firstNode;
firstNode = firstNode->next;
}
else if (theIndex < listSize - 1)
{
ChainNode<T>* p = firstNode;
for (int i = 0; i < theIndex - 1; i++)
{
p = p->next;
}
deleteNode = p->next;
p->next = p->next->next;
}
else
{
ChainNode<T>* p = firstNode;
for (int i = 0; i < theIndex; i++)
{
p = p->next;
}
deleteNode = p;
p->next = NULL;
}
listSize--;
delete deleteNode;
}
}
template<class T>
void Chain<T>::insert(int theIndex, const T& theElement)
{
if (checkIndex(theIndex))
{
if (theIndex == 0)
{
firstNode = new ChainNode<T>(theElement, firstNode);
}
else
{
ChainNode<T>* p = firstNode;
for (int i = 0; i < theIndex - 1; i++)
{
p = p->next;
}
p->next = new ChainNode<T>(theElement, p->next);
}
listSize++;
}
}
template<class T>
void Chain<T>::output()
{
ChainNode<T>* currentNode = firstNode;
while (currentNode != NULL)
{
cout << currentNode->element << " ";
currentNode = currentNode->next;
}
cout << endl;
}
template<class T>
bool Chain<T>::checkIndex(int theIndex) const
{
bool ret = !(theIndex < 0 || theIndex > listSize);
return ret;
}