单链表

1 没有头节点的单链表操作

实验证明:在某些情况下(比如拷贝构造函数,尾插法建表),不带头结点的单链表需要单独处理第一个元素。引入头结点的好处在于表中的每个元素的处理可以统一。

<pre name="code" class="cpp">// LinkList.cpp : 定义控制台应用程序的入口点。
//定义的链表不含头结点


#include <iostream>
using namespace std;

template<class Type>
//定义结点
struct Node
{
	Type data;
	Node<Type> *next;
};
//定义链表
template<class Type>
class LinkList
{
public:
	LinkList();//默认构造函数
	LinkList(const LinkList<Type>& otherList);//拷贝构造函数
	~LinkList();
	void createInsertHead();//头插法
	void createInsertRear();//尾插法
	void initList();//将链表归为初始状态
	bool isEmpty();//判断链表是否为空
	int  length();
	void destoryList();//销毁链表
	void getFirstData(Type& firstdata);
	void getData(int pos,Type& data);
	void insertFirst(Type newdata);//在表头插入新的元素
	void insertLast(Type newdata);//在表尾插入新的元素
	void deleteFirst(Type& data);//删除表头元素
	void deleteLast(Type& data);//删除表尾元素
	void reverse();
	void del_x(Type& data);    //删除所有值为data的结点
	const LinkList<Type>& operator=(const LinkList<Type>&otherList);//重载赋值运算符
	friend ostream& operator<< <>(ostream& cout,const LinkList<Type>& list);
private:
	int m_length;//链表中结点个数
	Node<Type>* head; //不使用头结点
};

template<class Type>
LinkList<Type>::LinkList()//默认构造函数
{
	//head = new Node<Type>;
	head = NULL;
	m_length = 0;
}

template<class Type>
LinkList<Type>::LinkList(const LinkList<Type>& otherList)//拷贝构造函数
{	
	head = NULL;
	m_length = otherList.m_length;
	
	Node<Type> *current;
	Node<Type> *otherListcurrent = otherList.head;
	while(otherListcurrent != NULL)
	{
		for (int i=1; i<=otherList.m_length; i++)
		{
			Node<Type> *newnode = new Node<Type>;
			newnode->data = otherListcurrent->data;
			newnode->next = NULL;

			if (i == 1)
			{
				head = newnode;
				current = head;
			}
			else
			{
				current->next = newnode;				
				current = current->next;				
			}
			otherListcurrent = otherListcurrent->next;
		}       
	}
}

template<class Type>
LinkList<Type>::~LinkList()
{
	destoryList();	
}

template<class Type>
void LinkList<Type>::createInsertHead()//头插法
{
	Node<Type> *newnode;
	cout<<"请输入链表的长度:";
	cin>>m_length;
	cout<<"请输入链表的元素:";
	for (int i=0; i<m_length; i++)
	{
	   newnode = new Node<Type>;
       cin>>newnode->data;
	   newnode->next = head;
	   head = newnode;
	}
}

template<class Type>
void LinkList<Type>::createInsertRear()//尾插法    尾插法和拷贝构造函数都有单独考虑第一个结点的情况
{
	Node<Type> *newnode;
	Node<Type> *current;
	cout<<"请输入链表的长度:";
	cin>>m_length;
	cout<<"请输入链表的元素:";
	for (int i=1; i<=m_length; i++)
	{
		newnode = new Node<Type>;
		cin>>newnode->data;
        newnode->next = NULL;
		if (i==1)
		{
			head = newnode;
			current = head;
		}
		else
		{
			current->next = newnode;
			current = current->next;
		}
	}
}

template<class Type>
void LinkList<Type>::initList()
{
	destoryList();
	head = NULL;
	m_length = 0;
}

template<class Type>
bool LinkList<Type>::isEmpty()
{
	if (head == NULL)
	{
		return true;
	}
	else 
	{
		return false;
	}
}

template<class Type>
int  LinkList<Type>::length()
{
	return m_length;
}

template<class Type>
void LinkList<Type>::destoryList()
{
	Node<Type> *current;
	while(head != NULL)
	{
		current = head;
		head = current->next;
		delete current;			
	}
	head = NULL;
	m_length = 0;
}

template<class Type>
void LinkList<Type>::getFirstData(Type& firstdata)
{
	if (head!=NULL)
	{
		firstdata = head->data;
	}
	else 
	{	
		cout<<"链表为空!"<<endl;
	}
}

template<class Type>
void LinkList<Type>::getData(int pos,Type& data)
{
   if (pos<1||pos>m_length)
   {
	   cout<<"指定的位置不正确!"<<endl;
   }
   else
   {
	   Node<Type> *current = head;
	   int i=0;
	   while(i<pos-1)
	   {
		   current = current->next;
		   i++;
	   }
	   data = current->data;
   } 
}

template<class Type>
void LinkList<Type>::insertFirst(Type newdata)
{
	Node<Type> *newnode = new Node<Type>;
	newnode->data = newdata;
	newnode->next = head;
	head = newnode;
	m_length++;
}

template<class Type>
void LinkList<Type>::insertLast(Type newdata)//尾部插入元素
{
	Node<Type> *current = head;
	while(current != NULL && current->next != NULL)
	{
		current = current->next;
	}
	Node<Type> *newnode = new Node<Type>;
	newnode->data = newdata;
	if (current==NULL)
	{
		/*newnode->next = current;
		current = newnode;*/
		newnode->next = head;
		head = newnode;
	}
	else
	{
		newnode->next = current->next;
		current->next = newnode;
	}	
	m_length++;
}

template<class Type>
void LinkList<Type>::deleteFirst(Type& data)
{
	if (isEmpty())
	{
		cout<<"链表为空!"<<endl;
	}
	else
	{
		if(m_length==1)
		{
			Node<Type> *temp = head;
			data = head->data;
			delete temp;
			head=NULL;
		}
		else
		{
			Node<Type> *temp = head;
			data = head->data;
			head = head->next;
			delete temp;
		}
		m_length--;
	}
}

template<class Type>
void LinkList<Type>::deleteLast(Type& data)
{
	if (isEmpty())
	{
		cout<<"链表为空!"<<endl;
	}
	else
	{
		if(m_length==1)
		{
			Node<Type> *current = head;
			data=current->data;
			delete(current);
			m_length--;
			head=NULL;
		}
		else
		{
			Node<Type> *current = head;
			for (int i=1; i<m_length-1; i++)
			{
				current = current->next;
			}
			Node<Type> *temp = current->next;
			data = temp->data;
			current->next = temp->next;
			delete temp;
			m_length--;
		}
		
	}	
}

template<class Type>
void LinkList<Type>::reverse()
{
	Node<Type> *current = head;
	head = NULL;
	if (current == NULL)
	{
		cout<<"链表为空!"<<endl;
	}
	else
	{
		while(current!=NULL)
		{
			Node<Type> *nextcurrent = current->next;
			current->next = head;
			head = current;
			current = nextcurrent;
		}
	}	
}

template<class Type>
void LinkList<Type>::del_x(Type& data)
{
	Node<Type> *current = head;
	Node<Type> *current1 = head;
	if (current == NULL)
	{
		cout<<"链表为空!"<<endl;
	}
	else
	{
		while(current->next!=NULL)
		{
			if(current->data==data)
			{
				Node<Type> *tmp=current->next;
				current->data=current->next->data;
				current->next=current->next->next;
				delete(tmp);
				m_length--;
			}
			else
			{
				current=current->next;
			}
		}
		if(current->data==data)
		{
		   if(m_length==1)
		   {
			   head=NULL;
			   m_length=0;
		   }
		   else
		   {
			   while(current1->next->next!=NULL)
				   current1=current1->next;
			   current1->next=NULL;
			   delete(current);
		   }
		}
	}
}

template<class Type>
const LinkList<Type>& LinkList<Type>::operator=(const LinkList<Type>&otherList)
{
	Node<Type> *current;
	Node<Type> *otherListcurrent = otherList.head;
	if (this!=&otherList)
	{
		if (!isEmpty())
		{
			initList();			
		}
		if (otherListcurrent!=NULL)
		{			
			for (int i=1; i<=otherList.m_length; i++) //或用while
			{
				Node<Type> *newnode = new Node<Type>;
				newnode->data = otherListcurrent->data;
				newnode->next = NULL;
				if (i==1)
				{
					head = newnode;
					current = head;//current始终指向链表的尾元素
				}
				else
				{
					current->next = newnode;
					current = current->next;
				}
				otherListcurrent = otherListcurrent->next;
			}
		}
	}
	return *this;
}

template<class Type>
ostream& operator<< <>(ostream& cout,const LinkList<Type>& list)
{
	Node<Type> *current = list.head;
	if (current==NULL)
	{
		cout<<"链表为空!"<<endl;
	}
	else
	{			
		while(current!=NULL)
		{
			cout<<current->data<<" ";
			current = current->next;
		}
		cout<<endl;
	}
	return cout;
}




int main(int argc, char* argv[])
{
	char a='a';
    LinkList<char> *list = new LinkList<char>;
	list->createInsertRear();
	cout<<"list:"<<*list;
	list->deleteLast(a);
	cout<<"list:"<<*list;
	system("pause");
	return 0;
}



2 带头节点的单链表

//单链表的初始化,建立,插入,查找,删除。//
//////////////////////////////////////////// 
#include <iostream>
using namespace std;
//////////////////////////////////////////// 
//定义结点类型
template<class Type>
struct Node
{
	Type data;				            //单链表中的数据域 
	struct Node<Type> *next;			//单链表的指针域 
};



template<class Type>
class  LinkList
{
public:	
	LinkList();//默认构造函数
	void LinkedListCreatF(); //单链表的建立1,头插法建立单链表
	void LinkedListCreatR(); //单链表的建立2,尾插法建立单链表
	void LinkedListInsert(int i,Type x);//单链表的插入,在链表的第i个位置插入x的元素
	void LinkedListDelete(Type x);//单链表的删除,在链表中删除值为x的元素
	const LinkList<Type>& operator=(const LinkList<Type>&otherList);//重载赋值运算符  
	friend ostream& operator<< <>(ostream& cout,const LinkList<Type>& list);  
private:  
	int m_length;//链表中结点个数  
	Node<Type> *head; //带头结点  
};

template<class Type>  
LinkList<Type>::LinkList()//默认构造函数  
{  
	head = new Node<Type>;
	head->next = NULL;  
	m_length = 0;  
}  


//单链表的建立1:头插法建立单链表
template<class Type>
void LinkList<Type>::LinkedListCreatF()
{
	Type x;							//x为链表数据域中的数据
	cout<<"输入链表数据:"<<endl;
	while(cin>>x)
	{
		Node<Type> *p=new Node<Type>;	//申请新的结点 
		p->data = x;//结点数据域赋值
		p->next=head->next;
		head->next=p;					//将结点插入到表头L-->|2|-->|1|-->NULL 
	}
} 

//单链表的建立2:尾插法建立单链表
template<class Type>
void LinkList<Type>::LinkedListCreatR()
{
	Node<Type> *r=head;					//r始终指向终端结点,开始时指向头结点 
	Type x;							//x为链表数据域中的数据
	cout<<"输入链表数据:"<<endl;
	while(cin>>x)
	{
		Node<Type> *p=new Node<Type>;	//申请新的结点 
		p->data = x;					//结点数据域赋值 
		r->next = p;					//将结点插入到表头L-->|1|-->|2|-->NULL 
		r = p; 
	}
	r->next = NULL; 
}

//单链表的插入,在链表的第i个位置插入x的元素
template<class Type>
void LinkList<Type>::LinkedListInsert(int i,Type x)
{
	Node<Type> *pre;						//pre为前驱结点 
	pre = L;
	int tempi = 0;
	for (tempi = 1; tempi < i; tempi++)
		pre = pre->next;					//查找第i个位置的前驱结点 
	Node<Type> *p=new Node<Type>;			//插入的结点为p
	p->data = x; 
	p->next = pre->next;
	pre->next = p;					 	
} 

//单链表的删除,在链表中删除值为x的元素
template<class Type>
void LinkList<Type>::LinkedListDelete(Type x)
{
	Node<Type> *p,*pre;					//pre为前驱结点,p为查找的结点。 
	p = L->next;
	while(p->data != x)				//查找值为x的元素 
	{	
		pre = p; 
		p = p->next;
	}
	pre->next = p->next;			//删除操作,将其前驱next指向其后继。 
	free(p);
} 

template<class Type>  
const LinkList<Type>& LinkList<Type>::operator=(const LinkList<Type>&otherList)  
{  
	Node<Type> *current;  
	Node<Type> *otherListcurrent = otherList.head->next;  
	if (this!=&otherList)  
	{  
		if (!isEmpty())  
		{  
			initList();           
		}  
		if (otherListcurrent!=NULL)  
		{             
			for (int i=1; i<=otherList.m_length; i++) //或用while  
			{  
				Node<Type> *newnode = new Node<Type>;  
				newnode->data = otherListcurrent->data;  
				newnode->next = NULL;  
				if (i==1)  
				{  
					head = newnode;  
					current = head;//current始终指向链表的尾元素  
				}  
				else  
				{  
					current->next = newnode;  
					current = current->next;  
				}  
				otherListcurrent = otherListcurrent->next;  
			}  
		}  
	}  
	return *this;  
}  

template<class Type>  
ostream& operator<< <>(ostream& cout,const LinkList<Type>& list)  
{  
	Node<Type> *current = list.head->next;  
	if (current==NULL)  
	{  
		cout<<"链表为空!"<<endl;  
	}  
	else  
	{             
		while(current!=NULL)  
		{  
			cout<<current->data<<" ";  
			current = current->next;  
		}  
		cout<<endl;  
	}  
	return cout;  
}  


int main(int argc, char* argv[])
{
	LinkList<int> *list = new LinkList<int>;
	list->LinkedListCreatR();
	cout<<"list:"<<*list;
	system("pause");
	return 0;
} 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值