您的位置:首页 > 理论基础 > 数据结构算法

线性表--链式描述(一)

2016-06-06 00:00 344 查看
摘要: 单向链表

单链表的基本操作

线性表的链式描述



单链表的插入操作



单链表的删除操作



单链表的实现

单链表类的实现:

[code=language-cpp]//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;
}

线性表的抽象类:

[code=language-cpp]//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;
};

异常处理:

[code=language-cpp]//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;
}
};


带头节点的循环链表 http://my.oschina.net/daowuming/blog/691504
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 单链表