双链表结点交换真的那么简单吗?||c语言解析

最近在做一道面试题,问道交换双链表的结点,真的就那么简单吗?

问题涉及的情况比较多,两个结点可能出现在头、尾以及中间,并且两个结点是否相邻都会影响操作的正确性,下面给出代码,包含了所有可能出现的情况。

struct Node
{
		struct Node* next;//下一个结点指针
		struct Node *pre;//上一个结点指针
		int data;//数据
};
struct BilList
{
		struct Node* first;//头节点
		struct Node *last;//尾结点
		int len;//链表长度
};

void swap(BilList *list,Node*node1,Node* node2)
{
	//判空
	assert(node1!=NULL||node2!=NULL);
	//两个不相等
	if(node1==node2)
		return;
	//临时结点,存储每个结点的前后结点
	Node*p,*q ,*s,*d;
	//每个结点都可能出现在首、中间、尾部等三种情况
	//如果node1为头部
	if(node1->pre==NULL)
	{
		//node2在尾部
		if(node2->next==NULL)
		{
			//两结点相邻
			if(node1->next==node2)
			{
				node1->next = NULL;
				node1->pre = node2;
				node2->pre = NULL;
				node2->next = node1;
			}
			//不相邻
			else
			{
				p = node1->next;
				q = node2->pre;
				node1->next = NULL;
				node1->pre = q;
				node2->pre = NULL:
				node2->next = p;
			}
			list->first = node2;
			list->last = node1;
		}
		//node2在中间
		else
		{
			//两结点相邻
			if(node1->next==node2)
			{
				 p= node2->next;
				 p->pre = node1;
				 node2->next = node1;
				 node2->pre = NULL;
				 node1->pre = node2;
				 node1->next = p;			 
			}
			//不相邻
			else
			{
				p= node2->next;
				q= node2->pre;
				s= node1->next;
				p->pre = node1;
				q->next = node1;
				node1->pre = q;
				node1->next = p;
				node2->next = s;
				s->pre = node2;
				node2->pre = NULL;
			}
			list->first = node2;
		}
	}
	//node1在尾部
	else if(node1->next==NULL)
	{
		//node2在头部
		if(node2 ->pre = NULL)
		{
			//两结点相邻
			if(node2->next==node1)
			{
				node2->next = NULL;
				node2->pre = node1;
				node1->pre = NULL;
				node1->next = node2;
			}
			//不相邻
			else
			{
				p = node2->next;
				q = node1->pre;
				node2->next = NULL;
				node2->pre = q;
				node1->pre = NULL:
				node1->next = p;
			}
			list->first = node1;
			list->last = node2;
		}
		//node2在中间
		else
		{
			//两结点相邻
			if(node2->next = node1)
			{
				p = node2->pre;
				node2->next = NULL;
				node2->pre = node1;
				node1->pre = p;
				node1->next = node2;
			}
			//不相邻
			else
			{
				p = node1->pre;
				q = node2->pre;
				s = node2->next;
				q->next = node1;
				node1->pre = q;
				s->pre = node1;
				node1->next = s;
				node2->next = NULL;
				node2->pre = p;
				p->next = node2;
			}
			list->last = node2;
		}
	}
	//node1在中间
	else
	{
		//node2在头部
		if(node2->pre ==NULL)
		{
			//两结点相邻
			if(node2->next==node1)
			{
				 p= node1->next;
				 p->pre = node2;
				 node1->next = node2;
				 node1->pre = NULL;
				 node2->pre = node1;
				 node2->next = p;			 
			}
			//不相邻
			else
			{
				p= node1->next;
				q= node1->pre;
				s= node2->next;
				p->pre = node2;
				q->next = node2;
				node2->pre = q;
				node2->next = p;
				node1->next = s;
				s->pre = node1;
				node1->pre = NULL;
			}
			list->first = node1;
		}
		//node2在尾部
		else if(node1->next = NULL)
		{
			//两结点相邻
			if(node1->next = node2)
			{
				p = node1->pre;
				node1->next = NULL;
				node1->pre = node2;
				node2->pre = p;
				node2->next = node1;
			}
			//不相邻
			else
			{
				p = node2->pre;
				q = node1->pre;
				s = node1->next;
				q->next = node2;
				node2->pre = q;
				s->pre = node2;
				node2->next = s;
				node1->next = NULL;
				node1->pre = p;
				p->next = node1;
			}
			list->last = node1;
		}
		//node2在中间
		else
		{
			//相邻
			if(node1->next==node2||node2->next ==node1)
			{
				if(node1->next ==node2)
				{
					p= node1->pre;
					q = node2->next;
					node1 ->next = q;
					q->pre = node1;
					node1->pre = node2;
					node2->next = node1;
					node2->pre = p;
					p->next = node2;
				}
				else
				{
					p= node2->pre;
					q = node1->next;
					node2 ->next = q;
					q->pre = node2;
					node2->pre = node1;
					node1->next = node2;
					node1->pre = p;
					p->next = node1;
				}
			}
			//不相邻
			else
			{
				p = node1 - >next;
				q = node1->pre;
				s = node2->next;
				d = node2->pre;
				
				s->pre = node1;
				node1->next = s;
				d->next = node1;
				node1->pre = d;

				p->pre = node2;
				node2->next = p;
				q->next = node2;
				node2->pre = q;
			}
		}
	}
	
	
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值