如何实现单链表交换任意两个元素(不包括头结点)

对于单链表而言,假设交换A、B两个节点,那么需要交换A与B的next指针以及A、B直接前驱的next指针。

需要注意特殊情况:1、当A与B相邻时:A->next = B;或者B->next = A;

         2、当A和B元素相同时,则没有必要交换。

         3、A与B有一个节点是头结点,不需要交换。

#include <iostream>
#include <algorithm>
#include "string.h"
#include "stdio.h"
#include <vector>
#include <deque>
#include<stack>
using namespace std;

struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
class List{
public:

    ListNode* CreatList(int* arr,int len)
    {
        int val;
        ListNode* pHead = new ListNode(arr[0]);
        ListNode* pCurrent=NULL;
        ListNode* rear = pHead;
        int count = 1;
        while(count<len)
        {
            ListNode* pCurrent = new ListNode(arr[count]);
            rear->next = pCurrent;
            rear = pCurrent;
            count++;
        }
        rear->next = NULL;
        return pHead;
    }
    void ShowList(ListNode* pHead)
    {
       while(pHead)
       {
           cout<<pHead->val<<" ";
           pHead = pHead->next;
       }
       cout<<endl;
    }
    ListNode* GetLastNode(ListNode* pHead)
    {
        ListNode* pNode = pHead;
        while(pNode->next!=NULL)
        {
            pNode=pNode->next;
        }
        return pNode;
    }
};
class Sort{
public:
    ListNode* changeList(ListNode* pHead,ListNode* pNode1,ListNode* pNode2)
    {
        if(pHead == NULL|| pNode1 == NULL || pNode2 == NULL)
            return pHead;
        //结点pNode1 等于pNode2
        if(pNode1->val == pNode2->val)
            return pHead;
        if(pNode1->next == pNode2)
        {
            ListNode* pre = FindPre(pHead,pNode1);
            if(pre == NULL)
                return pHead;
            pre->next = pNode2;
            pNode1->next = pNode2->next;
            pNode2->next = pNode1;
        }
        else if(pNode2->next == pNode1)
        {
            ListNode* pre = FindPre(pHead,pNode2);
            if(pre == NULL)
                return pHead;
            pre->next = pNode1;
            pNode2->next = pNode1->next;
            pNode1->next = pNode2;
        }
        else if(pNode1!=pNode2){
            ListNode* pre1 = FindPre(pHead,pNode1);
            ListNode* pre2 = FindPre(pHead,pNode2);
            ListNode* next1 = pNode1->next;
            ListNode* next2 = pNode2->next;
            pre1->next = pNode2;
            pNode2->next = next1;
            pre2->next = pNode1;
            pNode1->next = next2;
        }
        return pHead;
    }

    ListNode* FindPre(ListNode* pHead,ListNode* pNode)
    {
        ListNode* p = pHead;
        while(p)
        {
            if(p->next == pNode)
                return p;
            p = p->next;
        }
        return NULL;
    }

};
int array[7];
int n;
int number;
int first;
int second;
int main()
{
    cin>>n;

    for(int i=0;i<n;i++)
    {
        cin>>number;
        array[i]=number;
    }

    cin>>first;
    cin>>second;

    List list;
    Sort sort;
    ListNode* pHead1 = list.CreatList(array,sizeof(array)/sizeof(array[0]));
    ListNode* pNode1 = pHead1;
    ListNode* pNode2 = pHead1;
    for(int i=1;i<first;i++)
    {
        pNode1=pNode1->next;
    }
    cout<<pNode1->val<<endl;
    for(int i=1;i<second;i++)
    {
        pNode2 = pNode2->next;
    }
    cout<<pNode2->val<<endl;
    list.ShowList(pHead1);
    ListNode* p = sort.changeList(pHead1,pNode1,pNode2);
    //cout<<pEnd->val<<endl;
    list.ShowList(p);
    return 0;
}

 

转载于:https://www.cnblogs.com/omelet/p/6635548.html

### C语言中单链表节点交换实现 在C语言中,为了实现单链表中的两个节点之间的交换,通常有两种方式:一种是交换节点的数据部分;另一种则是调整指针使得两节点的位置互换。这里主要介绍后者。 对于需要交换两个节点A和B,在实际编程过程中会涉及到前驱节点pre_A、待交换的第一个节点cur_A、第二个节点cur_B及其后继节点next_B等四个重要位置。当只考虑简单情况下的相邻节点交换时,可以简化为仅处理三个节点间的相互关系变化[^3]。 下面给出一段具体的代码示例来展示如何完成这一过程: ```c // 定义单链表结构体 typedef struct ListNode { int val; struct ListNode *next; }ListNode; void swapNodes(ListNode **head, ListNode* a, ListNode* b){ if(a == NULL || b == NULL) return ; // 如果a恰好位于b前面,则需要额外寻找b的前置节点 bool is_adjacent = (a->next == b); ListNode *prev_a = NULL,*prev_b = NULL,*current = *head; // 寻找a,b各自的前置节点 while(current && current->next != a){ prev_a = current; current = current->next; } if(!is_adjacent){ current = *head; while(current && current->next != b){ prev_b = current; current = current->next; } } // 当至少有一个节点未被找到时退出函数 if (!a || !b) return; // 处理头结点的情况 if(prev_a==NULL){ (*head)=b; }else{ prev_a->next=b; } if(prev_b!=NULL&&!is_adjacent){ prev_b->next=a; } // 交换逻辑 ListNode* temp_next = b->next; if(is_adjacent){ b->next=a; a->next=temp_next; }else{ b->next=a->next; a->next=temp_next; } } ``` 此段代码实现任意给定两个非空节点`a``b`之间的一般化交换操作,并特别注意到了边界条件如其中一个节点可能是另一个节点的直接后续节点或者是头部节点等情况[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值