单链表的一些操作

本文详细介绍了五种针对两个已排序单链表的操作方法,包括链表合并、求交集及差集等,并提供了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单链表的一些操作,由于一些操作很类似,名字不好区分,现单列出来,可以直接在上篇文章的单链表中使用,VS2005调试通过

操作一:链表的合并

1、要求:两个单链表A和B,AB增C非增,C=A+B

注意:利用原表A和B,允许有相同元素

思想:

1、每次都插小的,大的留下继续比较

2、AB增C非增,则使用逆序插入

3、不能连续插入(每次要插入的结点总是要从原链表中截断,插入到C中)

代码:

template<class Type>
void LinkList<Type>::Merge(LinkList<Type>& A,LinkList<Type>& B)
{
	Node<Type>* currentA = A.Head->next;//currentA指向第一个结点
	Node<Type>* currentB = B.Head->next;//currentB指向第一个结点
	Node<Type>* currentC = A.Head;
	len = A.len + B.len;
	//处理C的头结点,利用A的头结点
	this->Head = A.Head;
	this->Head->next = NULL;
	delete B.Head;
	//处理之后的元素
	while(currentA!=NULL && currentB!=NULL)//
	{
		Node<Type>* temp;
		if (currentA->data > currentB->data)
		{
			temp = currentB;
			currentB = currentB->next;
			temp->next = currentC->next;
			currentC->next = temp;
		}
		else
		{
			temp = currentA;
			currentA = currentA->next;
			temp->next = currentC->next;
			currentC->next=temp;
		}
	}
	while (currentA!=NULL)
	{
		Node<Type>* temp;
		temp = currentA;
		currentA=currentA->next;
		temp->next = currentC->next;
		currentC->next = temp;
	}
	while (currentB!=NULL)
	{
		Node<Type>* temp;
		temp = currentB;
		currentB=currentB->next;
		temp->next = currentC->next;
		currentC->next = temp;
	}
}

2、要求:两个单链表A和B,AB增C增,C=A+B

注意:利用原表A和B的空间,允许有相同元素

思想:

1、每次都插小的,大的留下继续比较

2、AB增C增,则使用正序插入

3、可以连续插入(每次要插入的结点可以先不从原链表中截断,直到遇到一个大数,不指向插入操作时,才从原链表中截断)

代码:

template<class Type>
void LinkList<Type>::merge(LinkList<Type>& A,LinkList<Type>& B)
{
	Node<Type>* currentA = A.Head->next;//currentA指向第一个结点
	Node<Type>* currentB = B.Head->next;//currentB指向第一个结点
	Node<Type>* currentC = A.Head;
	len = A.len + B.len;
	//处理C的头结点,利用A的头结点
	this->Head = A.Head;
	this->Head->next = NULL;
	delete B.Head;
	//处理之后的元素
	while(currentA!=NULL && currentB!=NULL) 
	{
		if (currentA->data > currentB->data)
		{
			currentC->next = currentB;
			currentC = currentC->next;
			currentB = currentB->next;
		}
		else
		{
			currentC->next = currentA;
			currentC = currentC->next;
			currentA = currentA->next;
		}
	}
	if (currentA!=NULL)
	{
		currentC->next = currentA;
	}
	else
	{
		currentC->next = currentB;
	}
}

3、要求:两个单链表A和B,AB增C增,C=A交B

注意:

1、不能破坏原来空间(不利用原表A和B的空间)

2、AB中元素均无重复元素,但A和B中可能有相同元素 =》C中元素各不相同

思想:

1、每次都先抛弃小的,大的留下继续比较,找到相等的插入

2、AB增C增,则使用正序插入

代码:

template<class Type>
void LinkList<Type>::Intersect(const LinkList<Type>& A,const LinkList<Type>& B)
{
	Head = new Node<Type>;//为链表建立头结点
	Head->next = NULL;
	last = NULL;
	len =0;
	//定义处理指针,C指向最后一个元素,AB指向待处理的元素
	Node<Type>* currentA = A.Head->next;//currentA指向第一个结点
	Node<Type>* currentB = B.Head->next;//currentB指向第一个结点
	Node<Type>* currentC = Head;
	//处理之后的元素
	while(currentA!=NULL && currentB!=NULL) //每次都是先抛弃小的,找到相等的,就使用正序插入.
	{
		if (currentA->data > currentB->data)
		{
			currentB = currentB->next;
		}
		else if(currentA->data < currentB->data)
		{
			currentA = currentA->next;
		}
		else
		{
			Node<int>* newNode = new Node<int>;
			newNode->data = currentA->data;
			currentC->next=newNode;
			currentC = currentC->next;
			currentA = currentA->next;
			currentB = currentB->next;
			len++;
		}
	}
	currentC->next = NULL;
}

4、要求:两个单链表A和B,AB增C增,C=A交B,C中元素各不相同

注意:

1、不能破坏原来空间(不利用原表A和B)

2、AB中元素 可能有 重复元素,但要求C中元素各不相同

思想:

1、每次都先抛弃小的,大的留下继续比较,找到相等的插入

2、元素相等插入时,必须还要比较之前插入元素是不是和即将插入的元素相等

3、AB增C增,则使用正序插入

代码:

template<class Type>
void LinkList<Type>::Intersect(const LinkList<Type>& A,const LinkList<Type>& B)
{                                                                                     
	bool isFirst = true;//标志位,是不是第一次插入
	//为链表建立头结点
	Head = new Node<Type>;
	Head->next = NULL;
	last = NULL;
	len =0;
	//定义处理指针,C指向最后一个元素,AB指向待处理的元素
	Node<Type>* currentA = A.Head->next;//currentA指向第一个结点
	Node<Type>* currentB = B.Head->next;//currentB指向第一个结点
	Node<Type>* currentC = Head;
	//处理之后的元素
	while(currentA!=NULL && currentB!=NULL) //每次都是先抛弃小的,找到相等的,就使用正序插入.
	{
		if (currentA->data > currentB->data)
		{
			currentB = currentB->next;
		}
		else if(currentA->data < currentB->data)
		{
			currentA = currentA->next;
		}
		else
		{
			if (isFirst)
			{
				Node<int>* newNode = new Node<int>;
				newNode->data = currentA->data;
				currentC->next=newNode;
				currentC = currentC->next;
				isFirst=false;
				len++;
			}
			else
			{
				if (currentC->data != currentA->data)
				{
					Node<int>* newNode = new Node<int>;
					newNode->data = currentA->data;
					currentC->next=newNode;
					currentC = currentC->next;
					len++;
				}
			}
			currentA = currentA->next;
			currentB = currentB->next;
		}
	}
	currentC->next = NULL;
}

5、要求:两个单链表A和B,AB增C增,B=B-A,A中无重复,B中无重复

注意:

1、不能破坏A空间(不利用A),但是直接在B表中修改

思想:

1、每次都先抛弃小的,大的留下继续比较,找到相等的,则直接在原表删除

代码:

template<class Type>
void LinkList<Type>::Difference(const LinkList<Type>& A)//元素可以有重复的 B-A  ---没有设置尾指针
{
	//定义处理指针,C指向最后一个元素,AB指向待处理的元素
	Node<Type>* currentA = A.Head->next;//currentA指向第一个结点
	Node<Type>* currentC = Head->next;
	Node<Type>* trailCurrent = Head;
	//处理之后的元素
	while(currentA!=NULL && currentC!=NULL) //每次都是先抛弃小的,找到相等的,则直接在原表删除
	{
		if (currentA->data > currentC->data)
		{
			trailCurrent = currentC;
			currentC = currentC->next;
		}
		else if(currentA->data < currentC->data)
		{
			currentA = currentA->next;
		}
		else
		{	
			trailCurrent->next = currentC->next;
			delete currentC;
			currentC = trailCurrent->next;
			len--;
		}
	}
	if (currentC==NULL)
	{
		trailCurrent->next = NULL;
	}
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值