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

【数据结构】线性表(链表实现)

2016-03-09 20:18 483 查看
#ifndef __CHAIN_H__
#define __CHAIN_H__

#include <iostream>
using namespace std;

//VS平台下自己定义了nullptr = null = 0
//但是在gcc下没有定义
#ifndef nullptr
#define nullptr 0
#endif

/*
链表的节点元素类
*/
template <class T>
class ChainNode
{
public:
T data;									//数据域
ChainNode<T> *link;						//指向下一个节点
};

/*
链表类
*/
template <class T>
class Chain
{
public:
Chain()										//构造函数
{
first = nullptr;						//头指针清空
}
~Chain();									//析构函数
bool isEmpty() const						//判断链表是否为空
{
return first == nullptr;
}
int Length() const;							//获取链表长度
bool Find(int k, T& x) const;				//获取第k个元素
int Search(const T& x) const;				//在链表中查找元素x
Chain<T>& Delete(int k, T& x);				//从链表中删除一个元素
Chain<T>& Insert(int k, const T& x);		//向链表中插入一个元素
void Output(ostream& out) const;			//按照链表中遍历方向输出链表元素
private:
ChainNode<T> *first;						//指向第一个结点的指针
};

template<class T>
Chain<T>::~Chain()								//析构函数中将申请的堆空间都释放掉
{
ChainNode<T> *next;
while (first)
{
next = first->link;
delete first;
first = next;
}
}

/*获取链表的长度*/
template<class T>
int Chain<T>::Length() const
{
ChainNode<T> *current = first;
int len = 0;
while (current)
{
++len;
current = current->link;				//指针向后移动
}
return len;
}

/*返回第k个元素*/
template<class T>
bool Chain<T>::Find(int k, T& x) const
{
ChainNode<T> *current = first;
while(k--)
{
if (current->link)
return false;
current = current->link;
}
x = current;
return true;
}

/*
在链表中搜索元素x
*/
template<class T>
int Chain<T>::Search(const T& x) const
{
ChainNode<T> *current = first;
int index = 0;
while (current && current->data == x)
{
current = current->link;
++index;
}
if (!current)
return -1;
return index;
}

/*
从当前链表中删除一个元素
*/
template<class T>
Chain<T>& Chain<T>::Delete(int k, T& x)
{
if(k < 1 || k > Length())					//删除元素的位置不符合要求,则抛出异常
throw "不在范围内";

ChainNode<T> *p = first;
if(k == 1)									//如果要删除第一个元素
{
first = first->link;
delete p;
return *this;
}

k -= 2;
while(k--)									//将p移动到要删除元素的上一个位置
{
p = p->link;
}
ChainNode<T> *tmp = p->link;				//要删除的元素
if(!tmp->link)								//如果删除的是最后一个元素
{
p->link = nullptr;
delete tmp;
}
else
{
p->link = tmp->link;
delete tmp;
}
return *this;
}

/*
在第k个元素之后插入节点,和这个过程要分为两种情况:
1、插入点在链表的头部,也就是k=0的位置;
2、插入点在链表的中间。
*/
template<class T>
Chain<T>& Chain<T>::Insert(int k, const T& x)
{
ChainNode<T> *p = new ChainNode<T>;			//新节点
p->data = x;								//数据域
p->link = nullptr;							//指针域

//检查k是否在范围内
if(k < 0 || k > Length())					//插入的位置不满足要求,则抛出异常
throw "不在范围内";

if(0 == k)									//插入位置在0处,则插入到第一个节点的后面
{
if(!first)								//如果原链表为空
{
first = p;
return *this;
}
p->link = first->link;					//改变指针指向
first->link = p;
return *this;
}
else
{
ChainNode<T> *index = first;
k = k-1;
while(k--)								//index移动到要插入的前一个位置
{
/*if(!index->link)
throw "不在范围内";*/
index = index->link;				//index向后移动
}
p->link = index->link;					//修改指针指向
index->link = p;
return *this;
}
}

/*依次输出链表中的元素*/
template<class T>
void Chain<T>::Output(ostream& out) const
{
ChainNode<T> *p = first;
out << "Chain List: " << endl;
while (p)									//遍历当前链表依次输出元素值
{
out << p->data << " ";
p = p->link;
}
out << endl;
}

template <class T>
ostream& operator<<(ostream& out, const Chain<T>& x)
{
x.Output(out);
return out;
}

#endif // !__CHAIN_H__
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: