描述
利用单链表表示一个整数序列,请设计算法在空间复杂度为O(1)的前提下,两两交换其中相邻的结点。
注意:需要进行实际的结点交换,不可以仅改变结点内部的值。
输入
多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),当n=0时输入结束。
输出
对于每组数据分别输出一行,输出操作后的链表元素(元素之间用空格分隔)。
输入样例 1
4 1 2 3 4 5 5 2 6 3 6 5 2 7 1 4 1 1 2 0
输出样例 1
2 1 4 3 2 5 3 6 6 7 2 4 1 1 2
#include <bits/stdc++.h>
using namespace std;
struct listNode
{
int data;
listNode* link;
};
listNode* createList(vector<int>&arr){
if(arr.empty()) return nullptr;
listNode* head=nullptr;
listNode* tail=nullptr;
for(int i=0;i<arr.size();i++){
listNode* newNode=new listNode{arr[i],nullptr};
if(head==nullptr){
head=newNode;
tail=newNode;
}else{
tail->link=newNode;
tail=newNode;
}
}
return head;
}
listNode* changeList(listNode*& head) {
if (!head || !head->link) {
return head; // 如果链表为空或只有一个结点,直接返回
}
listNode* pre = nullptr; // 前一个结点
listNode* cur = head; // 当前结点
head = cur->link; // 更新链表头为第二个结点
while (cur && cur->link) { // 只要当前结点和下一个结点都存在
listNode* next = cur->link->link; // 获取下下个结点
listNode* second = cur->link; // 获取第二个结点
// 交换当前结点和第二个结点
second->link = cur; // 第二个结点的 link 指向当前结点
cur->link = next; // 当前结点的 link 指向下一个需要处理的结点
// 如果前一个结点存在,更新前一个结点的 link
if (pre) {
pre->link = second; //重要!
}
// 更新 pre 和 cur
pre = cur;
cur = next; // 移动到下一个结点
}
// while(cur){
// if(cur==head) pre=cur->link;
// listNode* temp=cur->link;
// listNode* temp2=cur->link->link;
// temp->link=cur;
// cur->link=temp2; 没有pre指针在第二次循环的时候直接断链了!!
// cur=temp2;
return head; // 返回新的链表头
}
int main(){
int n;
while (cin >> n && n != 0) {
vector<int> arr(n);
for(int i=0;i<n;i++){
int v;cin>>v;arr[i]=v;
}
listNode*head= createList(arr);
listNode* cur=changeList(head);
while(cur){
if(cur==head){
cout<<cur->data;
cur=cur->link;
}else{
cout<<" "<<cur->data;
cur=cur->link;
}
}
cout<<endl;
}
}