c++模板实现自定义链表及操作

今天花时间整理了一下C++模板方面的知识,搞了一个小程序作为实践

下面是头文件:chain.h

#include <iostream>
using namespace std;

template <class T> class Chain;

template <class T>
class ChainNode {
friend class Chain<T>;
private:
	T data;
	ChainNode<T> *link;
};

template<class T>
class Chain{
public:
	Chain() {first = 0;}
	~Chain() ;
	bool IsEmpty() const {return first == 0;}
	int Length() const;
	bool Find(int k, T& x) const;
	int Search(const T& x) const;
	void Erase();
	Chain<T>& Append(const T& 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; //指向第一个节点的指针
};

class OutOfBounds  
{  
public:
        // 构造函数,参数为错误代码  
        OutOfBounds(int errorId)  
        {  
            // 输出构造函数被调用信息  
            std::cout << "MyExcepction is called" << std::endl;  
            m_errorId = errorId;  
        }  
 
        // 拷贝构造函数  
        OutOfBounds( OutOfBounds& myExp)  
        {  
            // 输出拷贝构造函数被调用信息  
            std::cout << "copy construct is called" << std::endl;  
            this->m_errorId = myExp.m_errorId;  
        }  
 
       ~OutOfBounds()  
        {  
            // 输出析构函数被调用信息  
            std::cout << "~MyExcepction is called" << std::endl;  
        }  
 
       // 获取错误码  
        int getErrorId()  
        {  
            return m_errorId;  
        }  
 
private:      
        // 错误码  
        int m_errorId;  
};  
以下是源文件:chain.cpp

#include "chain.h"

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;
}

template<class T>
bool Chain<T>::Find(int k, T& x) const
{
//寻找链表中的第 k个元素,并将其传送至 x
//如果不存在第 k个元素,则返回false,否则返回true
	if (k < 1) return false;
	ChainNode<T> *current = first;
	int index = 1; // current 的索引
	while (index < k && current) {
		current = current->link;
		index++;
	}
	
	if (current) {x = current->data; return true;}
	return false; //  不存在第k个元素
}

template<class T>
int Chain<T>::Search(const T& x) const
{
	//寻找x,如果发现x,则返回x的地址
	//如果x不在链表中,则返回 0
	ChainNode<T> *current = first;
	int index = 1; // current 的索引
	while (current && current->data != x) {
		current = current->link;
		index++;
	}
	
	if (current) return index;
	return 0;
}

template<class T>
void Chain<T>::Output(ostream& out) const
{
	//将链表元素送至输出流
	ChainNode<T> *current;
	for (current = first; current; current = current->link)
	out << current->data << " ";
}

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

template<class T>
Chain<T>& Chain<T>::Delete(int k, T& x)
{
	//把第k个元素取至x,然后从链表中删除第 k个元素
	//如果不存在第 k个元素,则引发异常 OutOfBounds 
	if (k < 1 || !first)
		throw new OutOfBounds(-1); // 不存在第k个元素
	//p最终将指向第 k个节点
	ChainNode<T> *p = first;
	//将p移动至第k个元素,并从链表中删除该元素
	if (k == 1){ //p已经指向第k个元素
		first = first->link; //  删除之
	} else { //用q指向第k - 1个元素
		ChainNode<T> *q = first;	
		for (int index = 1; index < k - 1 && q; index++) {
			q = q->link;
		}
	
		if (!q || !q->link) {
			throw new OutOfBounds(-2); //不存在第k个元素
		}
		p = q->link; //存在第k个元素
		q->link = p->link; //从链表中删除该元素
	}
	//保存第k个元素并释放节点p
	x = p->data;
	delete p;
	return *this;
}

template<class T>
Chain<T>& Chain<T>::Insert(int k, const T& x)
{
	//在第k个元素之后插入x
	//如果不存在第 k个元素,则引发异常OutofBounds
	//如果没有足够的空间,则传递NoMem异常
	if (k < 0) throw new OutOfBounds(-1);
	//p最终将指向第 k个节点
	ChainNode<T> *p = first;
	//将p移动至第k个元素
	for (int index = 1; index < k && p; index++) 
		p = p->link;
	if (k > 0 && !p) throw new OutOfBounds(-1); //不存在第k个元素
	//插入
	ChainNode<T> *y=new ChainNode<T>;
	y->data = x;
	if (k)
	{//在p之后插入
		y->link = p->link;
		p->link = y;
	}
	else {//作为第一个元素插入
		y->link = first;
		first = y;
	}
	
	return *this;
}

template<class T>
void Chain<T>::Erase()
{
	//删除链表中的所有节点
	ChainNode<T> *next;
	while (first) {
		next = first->link;
		delete first;
		first = next;
	}
}

template <class T>
Chain<T>& Chain<T>::Append(const T& x)
{
	//在链表尾部添加x
	ChainNode<T> *y;
	ChainNode<T> *last;
	y = new ChainNode<T>;
	y->data = x;
	y->link = 0;
	last = first;
	if (first) {//链表非空
		while(last->link){
			last = last->link;
		}
		
		last->link = y;
		last = y;
	} else {//链表为空
		first = last = y;
	}
	
	return *this;
}

template<class T>
class ChainIterator {
public:
	T* Initialize(const Chain<T>& c)
	{
		location = c.first;
		if (location) 
			return &location->data;
		return 0;
	}
	
	T* Next()
	{
		if (!location)
			return 0;
		location = location->link;
		
		if (location) 
			return &location->data;
		return 0;
	}
	
private:
	ChainNode<T> *location;
};


int main(int argc, char **argv)
{
	Chain<int> intChain;
	int x = 5;
	intChain.Append(x);
	intChain.Append(1);
	intChain.Append(2);
	cout<<"after append:"<<intChain;
	intChain.Delete(intChain.Length(), x);
	cout<<std::endl<<x<<" was deleted"<<std::endl;
	cout<<"after delete:"<<intChain<<endl;
	intChain.Append(9);
	cout<<"after append:"<<intChain<<endl;
	intChain.Insert(3, 15);
	cout<<"after insert(3, 15):"<<intChain<<endl;
	cout<<"chain test"<<std::endl;
	return 0;
}

编译:g++ -o chain chain.cpp chain.h

运行:./chain

结果:

after append:5 1 2 
2 was deleted
after delete(intChain.Length()):5 1 
after append:5 1 9 
after insert(3, 15):5 1 9 15 
chain test

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值