学习笔记-简单模板链表类的C++实现 15/10/25

链表节点类和链表类代码如下,已在visual studio 2013中编译通过。

/*
以下定义了链表节点的类模板,包含两个私有成员,分别是数据域和指向下一个节点的指针(链接域)。
另外需要把链表类声明为其友元。
*/
template <class T>
class ChainNode
{
public:
	template<class T> friend class Chain;//将链表类声明为其友元,使Chain可访问ChainNode所有成员(务必注意友元类模板声明格式!)
private:
	T data; //链表类节点数据域
	ChainNode<T>* link;//链表类节点链接域
};
/*
以下定义了链表的类模板,包含一个头指针head,指向链表第一个节点。
链表实现了以下功能:判断是否为空链表、输出长度、查找、搜索、删除、插入节点、在尾部插入节点、输出链表。
*/
template <class T>
class Chain
{
public:

	Chain(){ head = NULL; tail = NULL; }
	~Chain();
	//删除所有节点
	void DeleteAll();
	//判断链表是否为空
	bool IsEmpty() const { return head == NULL; }//声明为常量函数成员,使其只能读取对象内容而无权修改,保证安全性
	//输出链表长度
	int Length() const;
	//查找链表第k个元素
	bool Find(int k, T& x) const;
	//搜索链表
	int Search(const T& x)const;//const保证实参x不被修改
	//删除一个节点
	void Delete(int k, T& x);
	//插入节点
	void Insert(int k, const T&x);
	//在尾部插入节点
	void Append(const T&x);
	//输出链表
	void Output() const;
private:
	ChainNode<T> *head;//头指针
	ChainNode<T> *tail;//尾指针
};
//链表的析构函数,删除链表所有节点
//从链表的头指针开始,先把下一个节点传递给next,再delete当前节点,以此类推直到头指针为空
template <class T>
Chain<T>::~Chain()
{
	ChainNode<T> *next;
	while (head)
	{
		next = head->link;
		delete head;
		head = next;//移至下一个将要delete的节点
	}
}
//删除所有节点,与析构函数相同
template <class T>
void Chain<T>::DeleteAll()
{
	ChainNode<T> *next;
	while (head)
	{
		next = head->link;
		delete head;
		head = next;//移至下一个将要delete的节点
	}
}
//输出链表长度
//利用临时节点指针从头指针开始进行遍历
template <class T>
int Chain<T>::Length() const
{
	int length = 0;
	ChainNode<T> *curr = head;
	while (curr)
	{
		length++;
		curr = curr->link;
	}
	return length;//返回长度值
}
//查找链表中第k个元素
//注意查找时循环的条件index < k && curr
template <class T>
bool Chain<T>::Find(int k, T& x) const
{
	if (k < 1)
		return false;
	ChainNode<T> *curr = head;
	int index = 1;//索引curr的位置
	while (index < k && curr)//使curr到达第k个元素
	{
		curr = curr->link;
		index++;
	}
	if (curr)//上述循环没到第k个节点时,curr一旦为空就将停止循环,此时将输出false
	{
		x = curr->data;
		return true;
	}
	return false;
}
//搜索节点
//利用临时指针节点遍历,直到为空或找到该值为止。为空找不到该值则返回0,找到则返回序号
template <class T>
int Chain<T>::Search(const T& x) const
{
	ChainNode<T> *curr = head;
	int index = 1;
	while (curr&&curr->data != x)
	{
		curr = curr->link;
		index++;
	}
	if (curr)
		return index;
	return 0;
}
//输出整个链表
template <class T>
void Chain<T>::Output() const
{
	ChainNode<T> *curr = head;
	while (curr)
	{
		cout << curr->data << " ";
		curr = curr->link;
	}
}
//删除第k个元素
//考虑三种情况:1.k<1或链表为空2.删除第一个节点3.删除其他节点
template <class T>
void Chain<T>::Delete(int k, T& x)
{
	if (k < 1 || !head)
		cout << "NO EXIST!";//抛出异常
	else if (k == 1)
	{
		x = head->data;
		head = head->link;
	}
	else
	{
		ChainNode<T> *q = head;
		for (index = 1; index < k - 1 && q; index++)//使q指向k-1项
		{
			q = q->link;
		}
		if (!q || (!q->link))
			cout << "NO EXIST!";
		else
		{
			ChainNode<T> *p = q->link;
			q->link = p->link;
			if (p == tail)
				tail = q;//如果删除的是最后一个节点,重定向尾指针
			delete p;
		}
	}
}
//在第k个元素之后插入x
//如果第k个元素不存在,抛出异常;另外考虑插入为头指针的情况
template <class T>
void Chain<T>::Insert(int k, const T& x)
{
	if (k < 0)
		cout << "NO EXIST!";
	ChainNode<T> *curr = head;
	for (int index = 1; index < k&&curr; index++)//使curr指向第k个节点
		curr = curr->link;
	if (k>0 && !curr)
		cout << "NO EXIST!";
	ChainNode<T> *ins = new ChainNode < T >;
	if (k)
	{
		ins->link = curr->link;
		curr->link = ins;
		if (ins->link == NULL)
			tail = ins;
	}
	else//k=0直接插入为头节点
	{
		ins->link = head;
		head = ins;
		if (ins->link == NULL)
			tail = ins;
	}
}
template <class T>
void Chain<T>::Append(const T&x)
{
	ChainNode<T> *curr = new ChainNode < T >;
	curr->data = x;
	curr->link = NULL;
	if (head)//链表非空
	{
		tail->link = curr;
		tail = curr;
	}
	else//链表为空
		head = tail = curr;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值