简易单链表模版(暂定最终版本)

自己写的一个单链表模版,模版的实现和定义是不可以分开两个文件写的 和平时写的类的不太一样 这个要注意,一开始没注意到这个 就出现了那个最讨厌的 unresolve external symbol 的错误 下面是代码 功能是一些比较常见的功能

这个是经过修改完善后的一个最终版本,以后有新想法 会再添加进去

mylist.h文件

#include<iostream.h>

template<class T> 
class My_list;

template<class T>
class Node //节点类
{
private:
	T data;
	Node<T> *next;
public:
	Node()
	{
		next=NULL;
	}

	Node(T d)
	{
		data=d;
		next=NULL;
	}
	friend My_list<T>;//声明为友元,在链表类中访问节点类的私有成员
};

template<class T>
class My_list
{
private:
	Node<T> *head,*tail;
	static bool flag;//判断是否已经排序的标志
public:
	My_list()
	{
		head=tail=new Node<T>();
	}
	
	~My_list()
	{
		clean();
		delete head;
		cout<<"析构函数~"<<endl;
	}

	Node<T> *create(T d)//创建节点
	{
		Node<T> *p=new Node<T>(d);
		return p;
	}
	
	void insert_front(Node<T> *p)//头插入
	{
		p->next=head->next;
		head->next=p;
	}
	
	void insert_rear(Node<T> *p)//尾插入
	{
		tail->next=p;
		tail=p;
	}
	
	bool empty()//判断链表是否为空
	{
		return (head->next==0);
	}

	int length()//计算表长
	{
		int size=0;
		Node<T> *p=head->next;
		while(p)
		{
			size++;
			p=p->next;
		}
		return size;
	}

	bool retrive(int k, T& x)//由x来返回k位置处的值
	{
		int pos=1;
		Node<T> *p=head->next;
		while(pos<k && p)
		{
			pos++;
			p=p->next;
		}
		if(!p && pos<=k)
			return false;
		else
		{
			x=p->data;
			return true;
		}
	}
	
	int locate(const T& x)//返回x在表中位置,找不到返回0
	{
		int pos=1;
		Node<T> *p=head->next;
		while(p->data!=x && p->next)
		{
			p=p->next;
			pos++;
		}
		if(!p || p->data!=x)
			pos=0;
		return pos;
	}
	
	bool insert(int k,T x)//在k位置后面插入x
	{
		if(k<0 || k>length())
			return false;
		int i=1;
		Node<T> *p=head->next;
		Node<T> *temp=new Node<T>(x);
		if(k==0)//插在头结点之后
		{
			temp->next=head->next;
			head->next=temp;
		}
		else
		{
			while(i<k && p)
			{
				i++;
				p=p->next;
			}
			temp->next=p->next;
			p->next=temp;
		}
		return true;
	}

	bool erase(int k,T& x)//删除k位置的节点,将k处的值给x
	{
		int i=1;
		Node<T> *p=head->next;
		if(k==1)
		{
			head->next=p->next;
			x=p->data;
			delete p;
			return true;
		}
		while(i<k-1 && p)
		{
			i++;
			p=p->next;
		}
		if(!p->next && i<=k-1)
			return false;
		else
		{
			Node<T> *temp=p->next;//temp指向k处节点
			p->next=temp->next;
			x=temp->data;
			delete temp;
			return true;
		}
	}

	void print_list() const//输出表
	{
		Node<T> *p=head->next;
		if(!p)
		{
			cout<<"List is empty."<<endl;
			return ;
		}
		while(p)
		{
			cout<<p->data<<'\t';
			p=p->next;
		}
		cout<<endl;
	}

	void clean()//删除整条链,表头结点在,那个由析构函数回收
	{
		Node<T> *p=head->next;
		while(p)
		{
			head->next=p->next;
			delete p;
			p=head->next;
		}
	}

	void select_sort()//用选择排序进行排序按升序排列
	{
		Node<T> *p,*q,*r;
		int t1,t2;
		p=head->next;
		while(p)
		{
			t1=p->data;
			q=p->next;
			while(q)
			{
				if(t1>q->data)
				{
					t1=q->data;
					r=q;
				}
				q=q->next;
			}
			if(t1!=p->data)
			{
				t2=p->data;
				p->data=t1;
				r->data=t2;
			}
			p=p->next;
		}
		flag=true;
	}

	void unique()//删除值重复的节点
	{
		if(!flag)
			select_sort();
		Node<T> *p=head->next;
		while(p->next)
		{
			while(p->data==p->next->data)
			{
				Node<T> *q=p->next;
				p->next=q->next;
				delete q;
			}
			p=p->next;
		}
	}

	bool inverse()//逆置整条链
	{
		Node<T> *p=head->next;
		Node<T> *tail=NULL,*r;
		while(p)
		{
			r=p->next;
			p->next=tail;
			tail=p;
			p=r;
		}
		head->next=tail;
		return true;
	}

};

template<class T>
bool My_list<T>::flag=false;


下面是一个测试代码 mian.cpp

 

#include"mylist.h"

int main()
{
	My_list<int> list;
	if(list.empty())
		cout<<"list is empty"<<endl;
	Node<int> *p;
	int x;
	while((cin>>x) && (x!=0))
	{
		p=list.create(x);
		list.insert_rear(p);
	}
	list.print_list();
	
	p=list.create(9);
	list.insert_front(p);
	list.print_list();
	
	cout<<"表长为:"<<list.length()<<endl;
	
	int pos;
	cout<<"输入要返回哪个位置:";
	cin>>pos;
	if(list.retrive(pos,x))
		cout<<x<<endl;
	
	int t,xx;
	cout<<"输入要返回哪个值的位置:";
	cin>>t;
	xx=list.locate(t);
	if(xx)
		cout<<xx<<endl;
	else
		cout<<"No find"<<endl;

	cout<<"输入要插入数字的位置和数值"<<endl;
	cout<<"位置:";
	cin>>pos;
	cout<<"值:";
	cin>>t;
	if(list.insert(pos,t))
		cout<<"insert is successful."<<endl;
	else
		cout<<"insert is fail."<<endl;
	list.print_list();

	int tt;
	cout<<"输入要删除的位置:";
	cin>>pos;
	if(list.erase(pos,tt))
		cout<<tt<<endl;
	list.print_list();

	list.select_sort();
	list.print_list();

	list.unique();
	list.print_list();
	
	cout<<"_______逆置_______"<<endl;
	if(list.inverse())
		cout<<"逆置成功"<<endl;
	list.print_list();

	cout<<"______清空表______"<<endl;
	list.clean();
	if(list.empty())
		cout<<"清空完成"<<endl;
	return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值