链表C++实现

#ifndef CHAIN_H
#define CHAIN_H

#include<iostream>
using namespace std;

/***************************************************************************************************/
//链表类节点定义 ChainNode
//note:1:链表描述中,数据对象实例每个元素在节点中描述,除本身数据对象外(数据域),还有一个与自身节点
//	   相关的节点位置信息成员,定义为link,通常由指向那个节点的指针描述(链接域)
//	   2:链表是线性表的另一种描述形式,因此其抽象结构与数组实现的线性表一致
//优点:1插入删除操作比数组表更快
//缺点:1需要额外空间保存链接指针
//     2访问第k个元素需要时间O(k)而数组为O(1)
/****************************************************************************************************/
template<class T>
class Chain;

template<class T>
class ChainNode
{
	friend Chain<T>;			//将Chain设为ChainNode的友元,这样Chain类对象就可以使用ChainNode的私有成员,除此外无特别含义
private:
	T data;						//节点数据
	ChainNode<T>* link;			//指向另一个节点的指针
};

/***************************************************************************************************************/
//链表类定义Chain
//
//
/***************************************************************************************************************/
template<class T>
class Chain
{
private:
	ChainNode<T>* first;				//指向第一个节点的指针
public:
	Chain();							//构造函数
	~Chain();							//析构函数
	bool IsEmpty()const;				//检查链表是否为空
	int Length()const;					//返回链表长度
	bool Find(int k,T& x)const;			//返回索引为k的元素,存入x中
	int Search(const T& x)const;		//在链表中查找x元素
	Chain<T>& Delete(int k,T& x);		//删除链表索引为k的元素,存入x中
	Chain<T>& Insert(int k,const T& x); //在索引k后插入元素x
	void Output(ostream& out)const;		//输出链表

	/******************************扩充函数************************************/
	void Erase();						//删除链表中所有节点
	Chain<T>& Append(const T& x);		//在链表尾部增加一个元素
};

/***************************************************************************************************************/
//链表类Chain实现
//
//
/***************************************************************************************************************/
//构造函数
template<class T>
Chain<T>::Chain()
{
	first=0;
}
//析构函数 时间复杂度O(n),n为链表长度
template<class T>
Chain<T>::~Chain()
{
	ChainNode<T>* p=first;
	while(first)
	{
		first=first->link;
		delete p;
		p=first;
	}
}

//检查链表是否为空
template<class T>
bool Chain<T>::IsEmpty()const
{
	return first==0;
}

//返回链表长度
template<class T>
int Chain<T>::Length()const
{
	int length=0;
	ChainNode<T>* p=first;
	while(p)
	{
		p=p->link;
		length++;
	}
	return length;
}

//返回索引为k的元素,存入x中
template<class T>
bool Chain<T>::Find(int k,T& x)const
{
	if(k<1)
	{
		return false;//从1开始,注意数组线性表实际从0开始
	}
	ChainNode<T>* p=first;
	int i=1;
	while(i<k&&p)
	{
		p=p->link;
		i++;
	}
	if(!p)
	{
		return false;
	}
	else
	{
		x=p->data;
		return true;
	}
}

//在链表中查找x元素
template<class T>
int Chain<T>::Search(const T& x)const
{
	int i=1;
	ChainNode<T> *p=first;
	while(p)
	{
		if(x==p->data)
		{
			return i;
		}
		else
		{
			p=p->link;
			i++;
		}
	}
	return 0;	//没找到
}

//删除链表索引为k的元素,存入x中
template<class T>
Chain<T>& Chain<T>::Delete(int k,T& x)
{
	if(k<1&&!first)
	{
		return *this;	//索引错误直接返回
	}
	ChainNode<T> *p=first;
	if(k==1)
	{
		first=p->link;
		delete p;
		return *this;
	}
	ChainNode<T> *d;
	int i=1;
	while(p&&i<k)
	{
		d=p;
		p=p->link;
		i++;
	}
	if(!p)
	{
		return *this;//索引越界,直接返回
	}
	d->link=p->link;
	x=p->data;
	delete p;
	return *this;

}

//在索引k后插入元素x
template<class T>
Chain<T>& Chain<T>::Insert(int k,const T& x)
{
	if(k<0)
	{
		return *this;
	}
	
	if(k==0)
	{
		ChainNode<T> *n=new ChainNode<T>;
		n->data=x;
		n->link=first;
		first=n;
		return *this;
	}
	int i=1;
	ChainNode<T> *p=first;
	
	while(i<k&&p)
	{
		
		p=p->link;
		i++;
	}
	if(p)
	{
		ChainNode<T> *q=new ChainNode<T>;
		q->data=x;
		q->link=p->link;
		p->link=q;
		return *this;
	}
	else
	{
		return *this;
	}
}

//输出链表
template<class T>
void Chain<T>::Output(ostream& out)const
{
	ChainNode<T> *p=first;
	while(p)
	{
		out<<p->data<<' ';
		p=p->link;
	}

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

/***************************扩充的函数定义**************************************/
//删除所有节点
template<class T>
void Chain<T>::Erase()
{
	ChainNode<T> *p=first;
	while(first)
	{
		first=first->link;
		delete p;
		p=first;
	}
}

//在链表尾部增加一个元素
template<class T>
Chain<T>& Chain<T>::Append(const T& x)
{
	if(!first)
	{
		ChainNode<T> *t=new ChainNode<T>;
		t->data=x;
		t->link=first;
		first=t;
		return *this;
	}
	ChainNode<T> *p=first;
	
	while(p->link)
	{
		
		p=p->link;
	}
	ChainNode<T> *n=new ChainNode<T>;
	n->data=x;
	p->link=n;
	n->link=0;
	return *this;
}

#endif // !CHAIN_H

可以在主函数里使用使用

#include "Chain.h"
void main(void)
{
	Chain<int> chain;
	chain.Append(1).Append(2).Append(3).Append(4).Append(5);
	cout<<chain<<endl;
	chain.Insert(3,65);
	cout<<chain<<endl;
	cout<<chain.Search(65)<<endl;
	cout<<chain.Search(33)<<endl;

	int a=0;
    cout<<chain.Find(7,a)<<endl;
	cout<<a<<endl;
	cout<<chain.Length()<<endl;
	chain.Delete(1,a);
	chain.Delete(2,a);
	cout<<chain<<endl;
	chain.Erase();
	cout<<chain<<endl;
	cin.get();
}

代码下载地址:http://download.csdn.net/detail/greenland1020/7892059

代码下载只有头文件,要使用的方法与文章中贴的代码一致,若有问题欢迎留言告知

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值