单链表的基本操作
线性表的链式描述
单链表的插入操作
单链表的删除操作
单链表的实现
单链表类的实现:
//chain.hpp
//-线性表链式描述
//-单链表
#pragma once
#include <iostream>
#include <ostream>
#include <sstream>
#include "linearList.h"
#include "illegalIndex.hpp"
//链表节点的结构定义
template <typename T>
struct chainNode {
T element;
chainNode<T> *next;
//methods
chainNode() {}
chainNode(const T& element) {
this->element = element;
}
chainNode(const T& element, chainNode<T>* next) {
this->element = element;
this->next = next;
}
};
//单链表chain类
template <typename T>
class chain : linearList<T>
{
public:
//constructor
chain();
chain(const chain<T>&);
~chain();
//ADT
bool empty() const {
return listSize == 0;
}
int size() const {
return listSize;
}
T& get(int theIndex) const;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void clear();
void insert(int theIndex, const T& theElement);
void insert_back(const T& theElement);
void output(std::ostream& out) const;
private:
void checkIndex(int theIndex) const;
chainNode<T> *firstNode, *lastNode;
int listSize;
};
template <typename T>
chain<T>::chain()
:listSize(0), firstNode(NULL), lastNode(NULL)
{
}
//复制构造函数
template <typename T>
chain<T>::chain(const chain<T>& theList)
{
this->listSize = theList.listSize;
//链表为空
if (listSize == 0) {
firstNode = lastNode = 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;
lastNode = targetNode;
}
//链表析构函数,删除链表所有节点
template <typename T>
chain<T>::~chain()
{
while (firstNode != NULL) {
chainNode<T>* nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
//确定索引theIndex在0和listSize-1之间
template <typename T>
void chain<T>::checkIndex(int theIndex) const
{
if (theIndex < 0 || theIndex >= listSize) {
throw illegalIndex("theIndex out of range");
}
}
//return an element of theIndex
//if not exists, throw exception
template <typename T>
T& chain<T>::get(int theIndex) const
{
checkIndex(theIndex);
chainNode<T>* currentNode = firstNode;
for (int i = 0; i < theIndex; ++i) {
currentNode = currentNode->next;
}
return currentNode->element;
}
//return index of the element that first appeared
//if element not exist,return -1
template <typename T>
int chain<T>::indexOf(const T& theElement) const
{
chainNode<T>* currentNode = firstNode;
int index = 0;
while (currentNode != NULL &&
currentNode->element != theElement)
{
currentNode = currentNode->next;
index++;
}
if (currentNode == NULL) {
return -1;
}
else {
return index;
}
}
//删除索引为theIndex的元素
//若不存在,则抛出异常
template <typename T>
void chain<T>::erase(int theIndex)
{
checkIndex(theIndex);
chainNode<T>* deleteNode;
if (theIndex == 0) {
deleteNode = firstNode;
firstNode = firstNode->next;
}
else {
//用p指向要删除节点的前驱节点
chainNode<T>* p = firstNode;
for (int i = 0; i < theIndex - 1; ++i) {
p = p->next;
}
deleteNode = p->next;
p->next = p->next->next;
if (theIndex == (listSize - 1)) {
lastNode = p;
}
}
listSize--;
delete deleteNode;
}
//删除所有的节点
template <typename T>
void chain<T>::clear()
{
while (firstNode != NULL) {
chainNode<T>* nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
lastNode = firstNode;
listSize = 0;
}
//在索引为TheIndex的位置上插入元素TheElement
template <typename T>
void chain<T>::insert(int theIndex, const T& theElement)
{
//索引无效
if (theIndex < 0 || theIndex > listSize) {
ostringstream s;
s << "error: list size = " << listSize;
throw illegalIndex(s.str());
}
if (theIndex == 0) {
firstNode = new chainNode<T>(theElement, firstNode);
lastNode = 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);
if (theIndex == listSize) {
lastNode = p->next;
}
else {
}
}
listSize++;
}
//在链表末尾插入元素为TheElement的节点
template <typename T>
void chain<T>::insert_back(const T& theElement)
{
chainNode<T>* newNode = new chainNode<T>(theElement, NULL);
if (firstNode == NULL) {
firstNode = lastNode = newNode;
}
else {
lastNode->next = newNode;
lastNode = newNode;
}
listSize++;
}
//把链表放入输入流
template <typename T>
void chain<T>::output(std::ostream& out) const
{
for (chainNode<T>* currentNode = firstNode;
currentNode != NULL;
currentNode = currentNode->next)
{
out << currentNode->element << " ";
}
}
//重载<<
template <typename T>
std::ostream& operator<< (std::ostream& out, const chain<T>& x)
{
x.output(out);
return out;
}
线性表的抽象类:
//linearList.h
//-线性表的抽象类
#pragma once
#include <ostream>
template <class T>
class linearList {
public:
//return ture, only if the linear list is empty
virtual bool empty() const = 0;
//return the numbers of element of linear list
virtual int size() const = 0;
//return an element of index for theIndex
virtual T& get(int theIndex) const = 0;
//return an index of the theElement for first appearence positon
virtual int indexOf(const T& theElement) const = 0;
//delete an element of index for theIndex
virtual void erase(int theIndex) = 0;
//delete all node of a list
virtual void clear() = 0;
//insert theElement into position for index is theIndex in the linear list
virtual void insert(int theIndex, const T& theElement) = 0;
//insert the linearlist into the ostream out
virtual void output(std::ostream& out) const = 0;
};
异常处理:
//illegalIndex.hpp
//-索引异常类
#pragma once
#include <string>
#include <iostream>
class illegalIndex
{
public:
illegalIndex()
{
std::cerr << "illegal index value" << std::endl;
}
illegalIndex(std::string theMessage)
{
std::cerr << theMessage << std::endl;
}
};