c++-swap nodes in pairs

本文介绍了一种链表操作算法,该算法通过不改变节点值仅调整节点位置的方式,实现链表中相邻节点的两两交换。文章详细解析了算法的具体步骤,并提供了完整的C++实现代码。

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

题目描述


Given a linked list, swap every two adjacent nodes and return its head.

For example,
Given1->2->3->4, you should return the list as2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.


这道题是将链表中的相邻的元素调换,而且不能改变其值,只能调换节点。

思路:

比如链表为1->2->3->4->5->6

将p设定为head,也就是1,q设定为2,r设定为3,他们的关系就是:

p=head;

q=head->next;

r=q->next;


然后将p->next指向r,q->next指向p,完成了p,q之间的调换,


p->next=r;

q->next=p;


接着移动p, q, r到下一个节点:

p=r;

q=r->next;

r=r->next->next;

再进行上述重复的调换,直到p或q为NULL,表示到最后了。



接下来贴出代码:


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *swapPairs(ListNode *head) {
		ListNode* res = new ListNode(0);
        res->next=head;
        ListNode* tmp=res;
        
        ListNode* p=head;
        ListNode* q=head->next;
        
        ListNode* r=q->next;

        while(q!=NULL && p!=NULL){
            q->next=p;
            p->next=r;
            tmp->next=q;
            tmp=p;
            p=r;
            q=r->next;
            r=r->next->next;
            
        }
        return res->next;
    }
};



要注意的是:

这里用了一个辅助指针作为表头,也就是res->next,这是链表中常用的小技巧,因为这样可以避免处理head的边界情况,一般来说要求的结果表头会有变化的会经常用这个技巧,大家以后会经常遇到。

ListNode* res = new ListNode(0);
res->next = head;

然后新建一个tmp节点,让其等于res,然后让这个tmp节点随着处理而变化,比如循环中第一个tmp->next=q, 也就是将q节点,放在头节点,也就是res->next,紧接着tmp=p,也就是将tmp节点移动到p,而p是q的下一个,也就相当于交换了p和q的位置。


转载于:https://www.cnblogs.com/sichenzhao/p/9320172.html

### C++ 链表交换节点对的实现 在 C++ 中,`std::list` 或 `forward_list` 可以用来表示双向或单向链表。对于 `swapPair` 函数的需求,通常是指将链表中的每两个相邻节点进行位置互换。 以下是基于 `std::list` 的一种实现方式: #### 使用 `std::list` 实现 `swapPairs` ```cpp #include <iostream> #include <list> void swapPairs(std::list<int>& lst) { auto it = lst.begin(); while (it != lst.end()) { auto next_it = std::next(it); if (next_it == lst.end()) break; // Swap values between current node and its adjacent one. std::iter_swap(it, next_it); // Move iterator two steps ahead. ++it; ++it; } } void printList(const std::list<int>& lst) { for (const auto& val : lst) { std::cout << val << " "; } std::cout << std::endl; } int main() { std::list<int> lst = {1, 2, 3, 4, 5}; std::cout << "Original list: "; printList(lst); swapPairs(lst); std::cout << "After swapping pairs: "; printList(lst); return 0; } ``` 上述代码通过迭代器遍历列表并调用 `std::iter_swap` 来完成相邻节点值的交换操作[^3]。 --- #### 基于自定义链表结构的实现 如果需要手动构建链表,则可以按照如下方式进行实现: ```cpp #include <iostream> struct ListNode { int value; ListNode* next; ListNode(int v) : value(v), next(nullptr) {} }; ListNode* createLinkedList(const std::initializer_list<int>& elements) { ListNode dummy(0); ListNode* tail = &dummy; for (auto elem : elements) { tail->next = new ListNode(elem); tail = tail->next; } return dummy.next; } void deleteLinkedList(ListNode* head) { while (head) { ListNode* temp = head; head = head->next; delete temp; } } void printList(ListNode* head) { while (head) { std::cout << head->value << " "; head = head->next; } std::cout << std::endl; } ListNode* swapPairs(ListNode* head) { ListNode dummy(0); dummy.next = head; ListNode* prev = &dummy; while (prev->next && prev->next->next) { ListNode* first = prev->next; ListNode* second = prev->next->next; // Swapping logic first->next = second->next; second->next = first; prev->next = second; // Move 'prev' pointer forward by two nodes. prev = first; } return dummy.next; } int main() { ListNode* head = createLinkedList({1, 2, 3, 4}); std::cout << "Original list: "; printList(head); head = swapPairs(head); std::cout << "After swapping pairs: "; printList(head); deleteLinkedList(head); return 0; } ``` 此版本实现了更底层的手动内存管理逻辑,并展示了如何调整指针来完成节点间的交换[^4]。 --- ### 性能分析 当仅需前向遍历时,优先选用 `std::forward_list` 而不是 `std::list` 是合理的,因为前者节省空间开销[^1]。然而,在本例中由于涉及频繁访问前后节点的操作,因此选择了支持双向前后的 `std::list` 结构作为基础容器。 另外需要注意的是,智能指针如 `std::shared_ptr` 和其辅助工具函数 `std::make_shared` 主要用于动态分配对象生命周期管理场景下简化资源释放过程[^2]。但在当前讨论范围内并不适用这些特性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值