交换两个链表节点

版权声明:若想转载,请在显眼的地方附上文章来源。 https://blog.csdn.net/Abudula__/article/details/82710659

在链表有关的问题当中,链表节点交换是一个非常 典型的一道题目,先给代码,后总结。

#include <iostream>
using namespace std;
struct Node
{
	int data;
	Node *next;
	Node(int _data=0,Node *_next=NULL):data(_data),next(_next){}
};

Node *create(int n,int *data)
{
	Node *head,*tail,*s;
	head = new Node;
	tail=head;
	for (int i = 0; i < n; i++)
	{
		s = new Node(data[i],NULL);
		tail->next = s;
		tail = s;
	}
	return head;
}

void display(Node *head)
{
	Node *p = head->next;
	while (p)
	{
		cout << p->data<<" ";
		p = p->next;
	}
	cout << endl;
}

Node *findprenode(Node *head,int preorder)
{
	Node *preNode;
	preNode = head;
	for (int i = 0; i < preorder; i++)
	{
		preNode = preNode->next;
	}
	return preNode;
}

Node *findnextnode(Node *head, int nextorder)
{
	Node *nextNode;
	nextNode = head;
	for (int i = 0; i < nextorder; i++)
	{
		nextNode = nextNode->next;
	}
	return nextNode;
}

void swap(Node *head, int preorder1, int nextorder1,int preorder2,int nextorder2)
{
	Node *preNode1, *nextNode1,*preNode2,*nextNode2;
	preNode1 = findprenode(head,preorder1);
	//cout << preNode1->data<<endl;
	nextNode1 = findnextnode(head,nextorder1);
	//cout << nextNode1->data << endl;
	preNode2 = findprenode(head, preorder2);
	//cout << preNode2->data << endl;
	nextNode2 = findnextnode(head, nextorder2);
	//cout << nextNode2->data<< endl;

	/*preNode2->next= preNode1->next;
	preNode2->next->next = nextNode1;

	preNode2->next = preNode1->next;
	preNode1->next->next = nextNode2;*/

	/*preNode1->next = preNode2->next;
	preNode2->next->next = nextNode1;

	preNode2->next = preNode1->next;
	preNode2->next->next = nextNode2;*/

	Node* tmp = preNode1->next;
	preNode1->next = preNode2->next;
	preNode2->next->next = nextNode1;

	preNode2->next = tmp;
	preNode2->next->next = nextNode2;
}

int main()
{
	int n, *data;
	cin >> n;
	data = new int[n];
	for (int i = 0; i < n; i++)
		cin >> data[i];
	Node *head=create(n, data);
	display(head);

	int t = 2;
	while (t--)
	{
		int order1, order2;
		cin >> order1 >> order2;
		if (order1 > order2)   //let order1 smaller than ordre2;
		{
			int temp = order2;
			order2 = order1;
			order1 = temp;
		}

		int preorder1 = order1 - 1;
		int nextorder1 = order1 + 1;
		int preorder2 = order2 - 1;
		int nextorder2 = order2 + 1;
		if (preorder1<0 || nextorder1>n || preorder2<0 || nextorder2>n)
		{
			cout << "error" << endl;
		}
		else
		{
			swap(head, preorder1, nextorder1, preorder2, nextorder2);
			display(head);
		}
	}
}

思路是先建立一个链表,这里有个小技巧,就是建立一个带有头节点的链表(这样做可以避免很多特殊情况),然后有些输入是错误的(节点数小于0或,大于总长度的情况),然后就是找到想交换的节点的前后节点,就是找到4个节点,然后画图,,画图,画图(重要的事情说3遍),然后连接。

只要涉及到swap,也就是交换,就是考虑一个很容易掉进坑里的问题,会容易出现a=b,b=a这种情况,这个代码注释掉的部分就是犯了这样的错误,然后引入了tmp,然后解决了这个问题。

猜你喜欢

转载自blog.csdn.net/Abudula__/article/details/82710659