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

单链表的基本操作

线性表的链式描述

 

单链表的插入操作

 

单链表的删除操作

 

单链表的实现

单链表类的实现:

//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;
	}
};

 

带头节点的循环链表    http://my.oschina.net/daowuming/blog/691504

转载于:https://my.oschina.net/daowuming/blog/687546

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值