带头结点的单链表实现(C++)

单链表在插入和删除操作时,有无头结点的实现是有区别的,总的来说,带有头结点的单链表实现起来比较方便,而不带头结点的单链表在链首插入和删除时要特殊处理,以下代码是带有头结点的单链表的实现。

//类定义、模板类的定义

#ifndef IncludeHeadNodeChain_H_H
#define IncludeHeadNodeChain_H_H
#include <iostream>
using std::ostream;
//自定义一个异常类,用于查找、插入和删除操作中越界时的异常提示
class OutOfBounds
{
public:
	void msg()
	{std::cout<<"越界"<<std::endl;}
};

template <class T>
class Node
{
private:
	//声明友元类
	template <class T>
	friend class IncludeHeadNodeChain;
	//定义节点数据
	T data;//数据域
	Node<T> * next;//指针域
};

template <class T>
class IncludeHeadNodeChain
{
private:
	Node<T> * head;
public:
	IncludeHeadNodeChain();
	~IncludeHeadNodeChain();
	bool isEmpty() const;
	bool find_k(int k, T& x) const;//用于发现第k个元素,返回给x
	int search_x(const T& x) const;//用于查找链表中是否有元素x,并返回x的位置
	int length() const {return head->data;}//返回链表长度
	IncludeHeadNodeChain<T>& insert(int k, const T& x);
	IncludeHeadNodeChain<T>& del(int k, T& x);
	void output(ostream& os) const;
	//友元类,用于输出链表元素
	template <class T>
	friend ostream& operator<<(ostream& os, const IncludeHeadNodeChain<T>& ihnc);
};

template <class T>
IncludeHeadNodeChain<T>::IncludeHeadNodeChain()
{
	//创建头结点
	head = new Node<T>;
	head->next = NULL;
	head->data = 0;//本例中头结点的数据域用于存放链表长度
}

template <class T>
IncludeHeadNodeChain<T>::~IncludeHeadNodeChain()
{
	Node<T> * cur = head;
	while (head)
	{
		cur = cur->next;
		delete head;
		head = cur;
	}
}

template <class T>
bool IncludeHeadNodeChain<T>::isEmpty() const
{
	return head->next == NULL;
}

template <class T>
bool IncludeHeadNodeChain<T>::find_k(int k, T& x) const
{
	if (k < 0)
		throw OutOfBounds();
	Node<T> * cur = head;//cur最终指向第k个元素

	for (int i = 0;i < k && cur;i++)
		cur = cur->next;
	if (!cur)
		return false;
	x = cur->data;
	return true;
}

template <class T>
int IncludeHeadNodeChain<T>::search_x(const T& x) const
{
	Node<T> * cur = head->next;
	int index = 1;
	while (cur && cur->data != x)
	{
		cur = cur->next;
		index++;
	}
	if (!cur)
		return -1;//返回-1表示未能找到x
	return index;
}

template <class T>
IncludeHeadNodeChain<T>& IncludeHeadNodeChain<T>::insert(int k, const T& x)
{
	if (k < 0)
		throw OutOfBounds();
	Node<T> * cur = head;
	for (int i = 0;i < k && cur;i++)
		cur = cur->next;
	if (k > 0 && !cur)//若不存在第k个元素
		throw OutOfBounds();
	Node<T> * ins = new Node<T>;//带插入元素
	ins->data = x;
	//执行插入操作
	ins->next = cur->next;
	cur->next = ins;

	head->data++;//链表长度加1
	return *this;
}

template <class T>
IncludeHeadNodeChain<T>& IncludeHeadNodeChain<T>::del(int k, T& x)
{
	if (k < 1) throw OutOfBounds();
	Node<T> * pre = head;//pre最终指向第k个元素的上一个元素
	for (int i = 0;i < k-1 && pre;i++)
		pre = pre->next;
	if (!pre || !pre->next)
		throw OutOfBounds();
	Node<T> * cur = pre->next;//cur指向第k个元素
	//执行删除操作
	pre->next = cur->next;
	x = cur->data;
	delete cur;

	head->data--;//链表长度减1
	return *this;
}

template <class T>
void IncludeHeadNodeChain<T>::output(ostream& os) const
{
	Node<T> * cur = head->next;//cur指向第一个节点
	while (cur)
	{
		std::cout<<cur->data<<" ";
		cur = cur->next;
	}
	std::cout<<std::endl;
}
 
template <class T>
ostream& operator<<(ostream& os, const IncludeHeadNodeChain<T>& ihnc)
{
	ihnc.output(os);
	return os;
}
#endif
使用以下代码进行测试:

#include <iostream>
#include "linkedlist.h"

int main()
{
	using std::cout;
	using std::endl;

	IncludeHeadNodeChain<int> chain;
	try
	{
		chain.insert(0,4);
		chain.insert(1,56);
		chain.length();
		//下面代码将出现异常
		int x;
		chain.del(3,x);
	}
	catch(OutOfBounds& o)
	{o.msg();}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值