加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-15 05:59:04 所属栏目:安全 来源:网络整理
导读:#ifndef __CHAIN_H__#define __CHAIN_H__#include iostreamusing namespace std;//VS平台下自己定义了nullptr = null = 0//但是在gcc下没有定义#ifndef nullptr#define nullptr 0#endif/*链表的节点元素类*/template class Tclass ChainNode{public:T data;/


#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__

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读