首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

尝试在没有双指针的纯C语言中交换链表中的两个相邻节点

在没有双指针的纯C语言中交换链表中的两个相邻节点,可以使用以下步骤:

  1. 首先,判断链表的头节点是否为空,如果为空则直接返回。
  2. 定义三个指针,分别为prev、curr和next。prev指向当前节点的前一个节点,curr指向当前节点,next指向当前节点的后一个节点。
  3. 判断链表的头节点是否为要交换的节点之一,如果是,则需要重新调整链表的头节点。若不是,则开始遍历链表。
  4. 进入循环遍历链表,每次迭代中,交换curr和next节点的位置。
  5. 在交换节点位置之前,需要判断next节点是否为空,如果为空则说明已经到达链表末尾,无法再交换节点了。在交换节点之前,还需要判断prev节点是否为空,如果为空则说明curr节点为头节点,需要重新调整链表的头节点。
  6. 完成节点交换后,将prev指向next节点,将curr指向next节点的下一个节点。
  7. 继续进行下一轮的节点交换,直到遍历完整个链表。

下面是使用纯C语言实现交换链表中两个相邻节点的示例代码:

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>

// 定义链表节点结构体
struct ListNode {
    int val;
    struct ListNode* next;
};

// 创建链表节点
struct ListNode* createNode(int val) {
    struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
    newNode->val = val;
    newNode->next = NULL;
    return newNode;
}

// 交换链表中两个相邻节点
struct ListNode* swapNodes(struct ListNode* head) {
    if (head == NULL || head->next == NULL) {
        return head;
    }

    struct ListNode* prev = NULL;
    struct ListNode* curr = head;
    struct ListNode* next = head->next;

    // 判断链表头节点是否为要交换的节点
    if (curr->val > next->val) {
        head = next;
    }

    while (next != NULL) {
        curr->next = next->next;
        next->next = curr;
        
        if (prev != NULL) {
            prev->next = next;
        }
        
        prev = curr;
        curr = curr->next;
        
        if (curr != NULL) {
            next = curr->next;
        } else {
            next = NULL;
        }
        
        if (next != NULL && curr->val > next->val) {
            prev->next = next;
            head = next;
        }
    }

    return head;
}

// 打印链表
void printList(struct ListNode* head) {
    struct ListNode* curr = head;
    while (curr != NULL) {
        printf("%d ", curr->val);
        curr = curr->next;
    }
    printf("\n");
}

int main() {
    // 创建链表
    struct ListNode* head = createNode(1);
    head->next = createNode(2);
    head->next->next = createNode(3);
    head->next->next->next = createNode(4);
    head->next->next->next->next = createNode(5);

    // 打印原始链表
    printf("原始链表:");
    printList(head);

    // 交换相邻节点
    head = swapNodes(head);

    // 打印交换后的链表
    printf("交换后的链表:");
    printList(head);

    return 0;
}

在以上示例代码中,我们使用了三个指针prev、curr和next来交换链表中的相邻节点,通过迭代遍历链表,并根据节点的值大小进行相应的节点交换操作。最后打印出交换后的链表。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

力扣每日一刷(2023.10.2)

思路 本题有两种解法 ,一种是直接使用指针来改变节点指向; 另一种就是使用栈来进行一次进出栈 使用指针 首先定义一个虚拟头节点pre, 置为空,然后定义一个nextNode指针, 用于指向当前节点下一个...,两两交换其中相邻节点,并返回交换链表节点。...[0, 100] 内 0 <= Node.val <= 100 思路: 这道题本质上和反转链表是一个道理, 都是通过改变节点指针方向来实现, 不过本题只需要改变相邻两个即可。...如果两个链表不存在相交节点,返回 null 。 图示两个链表节点 c1 开始相交: 题目数据 保证 整个链式结构不存在环。 注意,函数返回结果后,链表必须 保持其原始结构 。...— 请注意相交节点值不为 1,因为链表 A 和链表 B 之中值为 1 节点 (A 第二个节点和 B 第三个节点) 是不同节点

8710

JavaScript刷LeetCode拿offer-高频链表题1

JS 可以表现为一个拥有 val 和 next 属性对象,所以遇到形如交换两个链表节点时候,千万不能交换两个链表 val 值,虽然 LC 有一些题是可以过,但是实际上是不合理,而且一旦出现这种思想...相交链表 就会理解不了;记住,链表是一个数据结构,不是一个值,可以类比成一个对象,交换链表比如不是简单交换值;都是中等题这里选都是按照 LC 火热排序,中等难度题,感觉链表学习做特别难没太大必要,...,但是 LC 链表序列化以数组形式存在,就会迷惑为什么不是 aTail 这个节点就是相交节点,需要特别注意所以我们一起走两个链表,直到其中一个结束,找出可能剩下没走完那个链表,就可以判断除...交换链表节点分析先用指针求出正序第 k 个节点 first 和反序第 k 个节点 second现在要交换 first 和 second , 需要先判断他们两个节点是不是相邻相邻节点可以直接处理如果不是相邻节点...链表下一个更大节点分析 -- 指针指针 w 遍历整个链表,读指针 r 找到第一个比当前 w 大节点,并返回对应值,如果 r 走完整个链表没找到,则返回 0这题和上一题一样,都是循环遍历,找到符合要求

45750
  • JavaScript刷LeetCode--高频链表

    JS 可以表现为一个拥有 val 和 next 属性对象,所以遇到形如交换两个链表节点时候,千万不能交换两个链表 val 值,虽然 LC 有一些题是可以过,但是实际上是不合理,而且一旦出现这种思想...相交链表 就会理解不了;记住,链表是一个数据结构,不是一个值,可以类比成一个对象,交换链表比如不是简单交换值;都是中等题这里选都是按照 LC 火热排序,中等难度题,感觉链表学习做特别难没太大必要,...,但是 LC 链表序列化以数组形式存在,就会迷惑为什么不是 aTail 这个节点就是相交节点,需要特别注意所以我们一起走两个链表,直到其中一个结束,找出可能剩下没走完那个链表,就可以判断除...交换链表节点分析先用指针求出正序第 k 个节点 first 和反序第 k 个节点 second现在要交换 first 和 second , 需要先判断他们两个节点是不是相邻相邻节点可以直接处理如果不是相邻节点...链表下一个更大节点分析 -- 指针指针 w 遍历整个链表,读指针 r 找到第一个比当前 w 大节点,并返回对应值,如果 r 走完整个链表没找到,则返回 0这题和上一题一样,都是循环遍历,找到符合要求

    53360

    JavaScript刷LeetCode拿offer-高频链表

    JS 可以表现为一个拥有 val 和 next 属性对象,所以遇到形如交换两个链表节点时候,千万不能交换两个链表 val 值,虽然 LC 有一些题是可以过,但是实际上是不合理,而且一旦出现这种思想...相交链表 就会理解不了;记住,链表是一个数据结构,不是一个值,可以类比成一个对象,交换链表比如不是简单交换值;都是中等题这里选都是按照 LC 火热排序,中等难度题,感觉链表学习做特别难没太大必要,...,但是 LC 链表序列化以数组形式存在,就会迷惑为什么不是 aTail 这个节点就是相交节点,需要特别注意所以我们一起走两个链表,直到其中一个结束,找出可能剩下没走完那个链表,就可以判断除...交换链表节点分析先用指针求出正序第 k 个节点 first 和反序第 k 个节点 second现在要交换 first 和 second , 需要先判断他们两个节点是不是相邻相邻节点可以直接处理如果不是相邻节点...链表下一个更大节点分析 -- 指针指针 w 遍历整个链表,读指针 r 找到第一个比当前 w 大节点,并返回对应值,如果 r 走完整个链表没找到,则返回 0这题和上一题一样,都是循环遍历,找到符合要求

    40020

    JavaScript刷LeetCode拿offer-高频链表题1

    JS 可以表现为一个拥有 val 和 next 属性对象,所以遇到形如交换两个链表节点时候,千万不能交换两个链表 val 值,虽然 LC 有一些题是可以过,但是实际上是不合理,而且一旦出现这种思想...相交链表 就会理解不了;记住,链表是一个数据结构,不是一个值,可以类比成一个对象,交换链表比如不是简单交换值;都是中等题这里选都是按照 LC 火热排序,中等难度题,感觉链表学习做特别难没太大必要,...,但是 LC 链表序列化以数组形式存在,就会迷惑为什么不是 aTail 这个节点就是相交节点,需要特别注意所以我们一起走两个链表,直到其中一个结束,找出可能剩下没走完那个链表,就可以判断除...交换链表节点分析先用指针求出正序第 k 个节点 first 和反序第 k 个节点 second现在要交换 first 和 second , 需要先判断他们两个节点是不是相邻相邻节点可以直接处理如果不是相邻节点...链表下一个更大节点分析 -- 指针指针 w 遍历整个链表,读指针 r 找到第一个比当前 w 大节点,并返回对应值,如果 r 走完整个链表没找到,则返回 0这题和上一题一样,都是循环遍历,找到符合要求

    35130

    精读《算法 - 滑动窗口》

    指针也并不局限在数组问题,像链表场景 “快慢指针” 也属于指针场景,其快慢指针滑动过程本身就会产生一个窗口,比如当窗口收缩到某种程度,可以得到一些结论。...一般指针是暴力算法优化版,所以: 如果题目较为简单,且是数组或链表问题,往往可以尝试指针是否可解。 如果数组存在规律,可以尝试指针。...题目如下: 给你一个包含 n 个整数数组 nums,判断 nums 是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复三元组。...链表倒数第k个节点 链表倒数第k个节点是一道简单题,题目如下: 输入一个链表,输出该链表倒数第 k 个节点。为了符合大多数人习惯,本题从 1 开始计数,即链表节点是倒数第 1 个节点。...这道题指针移动规则比较巧妙,与上面普通题目不一样,重点不是是否会运用滑动窗口算法,而是能否找到移动指针规则。 当然你可能会说,为什么两个指针要定义最两端,而非别的地方?

    61720

    数据结构:一般线性表

    顺序表 顺序表特点是表中元素逻辑顺序与其物理顺序相同 特点: 最主要特点是可以进行随机访问,即通过首地址和元素序号可以O(1)时间内找到指定元素 存储密度高,每个结点只存储数据元素 逻辑上相邻元素物理上也相邻...单链表 线性表链式存储又称为单链表,它是通过一组任意存储单元来存储线性表数据元素。为了建立数据与元素之间线性关系,对每个链表节点,除了存放元素自身信息之外,还需要一个存储指向其后继指针。...data为数据域,存放数据元素;next为指针域,存放其后继节点地址。 image.png 为了操作上方便,链表第一个节点之前附加一个节点,称为头结点。...链表 3. 循环链表 循环单链表:循环单链表和单链表区别在于,表中最后一个节点指针不是NULL,而是指向头结点 循环链表: 4....总体来说静态链表没有链表使用起来方便,但是一些不支持指针高级语言中,这是一种非常巧妙方法。

    95931

    力扣刷题篇——链表

    目录  两两交换链表结点 题目描述: 解题思路: 代码如下: 删除链表倒数第N个结点 题目描述: 图解 :  代码附上:  友友们 大家好呀 我是你们小王同学 今天小王同学给大家带来两道经典链表练习...两两交换链表节点 - 力扣(LeetCode) 题目描述:  解题思路: 根据题意要求 不能单纯改变节点内部值,并且需要将实际节点进行交换 这道题小王同学采用是递归方式 具体操作看小王代码...此时不需要交换咱们相邻节点 直接返回 头节点就行了 if(head==null||head.next==null) return head; //获取当前节点下一个节点...删除链表倒数第 N 个结点 题目描述: 解题思路:  这道题就是一道经典指针题型,如果我们要删除倒数第N个节点 定义两个指针 fast 和slow 让fast移动n步,然后让fast和slow...图解 : 定义fast和slow两个指针,初始化值为虚拟头结点 我们以第一个n=2为例子来解释  第一步: 第二步:   首先让我们fast指针先走n+1步 这里n为2,n+1原因是这样slow

    19720

    【一个神奇数据结构-异或链表】拥有单链表空间,效率如链表

    最开始学编程时候,我们交换两个变量,有两种方法//方法一c=aa=bb=c//方法二a=a+bb=a-ba=a-b从第二种方法我们可以看出,我们可以通过两个相加,然后特别取出某个数那么想一想?...思路和上面通过加法有点像链表看这个应该都会,我直接上图我们把中间某一个节点单独提取出来,就会是这样其中prev是上一个节点地址,next是下一个节点地址属于两个指针域,那么我们能否用一个指针域来代替两个呢如果能够代替...,那么假设我们某个节点前驱节点地址如果是已知,那么他后继节点地址也能够退出来,比如我们可以设当前节点指针与为prev+next,然后上一个节点地址是prev,那么下一个节点地址不就是prev...⊕ addr(C)获取B后继C地址addr(C) = B->xorPtr ⊕ addr(A)通过以上几种操作,就可以遍历整个链表处理添加、插入、删除等操作时同普通双向链表类似注意:这些异或和加法相关操作都是针对指针本身...*xorptr=NULL;//存储相邻两个节点地址异或值}Node;inline Node* xorp(Node* a, Node* b){ return (Node *)((unsigned

    58333

    —-对双向链表结(节)点成员排序(冒泡排序)「建议收藏」

    双向链表定义 ---- 【百度百科】 双向链表也叫链表,是链表一种,它每个数据结点中都有两个指针,分别指向直接后继和直接前驱。...所以,从双向链表任意一个结点开始,都可以很方便地访问它前驱结点和后继结点。 链表每个节点成员由两部分组成: 1. 数据域:专门用来保存各个成员信息数据。 2....双向链表节点成员排序(冒泡排序) ---- 排序之前我们需要明确一点: 因为有时候程序员写代码时为了链表方便操作会专门创建一个表头(头结点),即不存放数据表头...p总是Pn前面,那也就是说满足交换位置条件之后进行位置交换交换之后两个临时指针位置就随之交换交换过程,假如有尾结点,那么pn后向指针指向NULL,随之 pn->pnext->prev 就会出现段错误...//定义两个临时指针来进行数据处理 PSTU p1=head; //p和pn总是两个相邻节点,且pn

    96340

    指针法:总结篇!

    所以此时使用指针法才展现出效率优势:「通过两个指针一个for循环下完成两个for循环工作。」...使用指针法,「定义两个指针(也可以说是索引下表),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。」,时间复杂度是O(n)。...思路还是很简单,代码也不长,但是想在白纸上一次性写出bugfree代码,并不是容易事情。 链表求环,应该是指针链表里最经典应用,链表:环找到了,那入口呢?...「使用快慢指针指针法),分别定义 fast 和 slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环...,讲到使用哈希法可以解决1.两数之和问题 其实使用指针也可以解决1.两数之和问题,只不过1.两数之和求两个元素下标,没法用指针,如果改成求具体两个元素数值就可以了,大家可以尝试指针做一个

    1.6K10

    【数据结构】-----链表(小白必看!!!)

    c言中小小白-CSDN博客c言中小小白关注算法,c++,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域. https://blog.csdn.net/bhbcdxb123...链表结点中有两个指针prior和next,分别指向前驱结点和后继结点。  ...由于每个节点都有指向前一个节点指针,可以从任一节点开始向前或向后遍历链表,这对于某些操作如逆序遍历或者特定节点前后插入节点非常方便。 其次,链表更便于节点删除和插入。...链表,要删除或插入一个节点,需要找到其前一个节点,而在链表,只需要修改节点本身指针即可,无需额外查找操作,从而提高了操作效率。...然而,链表相比单链表需要额外空间来存储前一个节点指针,因此会占用更多内存。某些情况下,如果对内存占用有限制,可能需要权衡选择是否使用链表

    9010

    Redis系列(二)底层数据结构之链表

    我读了几本 Redis 相关书籍,尝试去了解它具体实现,将一些底层数据结构及实现原理记录下来。 本文将介绍 Redis 中最基础 linkedlist(链表) 实现方法。...定义 链表,是一个非常常用数据结构,很多编程语言里都有实现,比如 Java LinkedList. 但是 C 语言没有。...带有头指针和尾指针 list 结构,保存了当前链表表头指针和表尾指针,因此可以快速从头进行遍历或者从尾部开始遍历。...带有长度计数器 list 结构中保存了当前链表长度长度,因此对链表长度统计时间复杂度是 O(1). 总结 链表是一个比较常用数据结构,很多编程语言中都有实现,读者们接触也很多。...因此本文没有专门去强调它实现方法,而是大概介绍了下 Redis 链表一个结构及其主要特性: Redis 链表链表。 封装了 list 结构,保存了链表头尾指针以及链表长度。

    71820

    数据结构(2):链表(上)

    引入头结点后,可以带来两个优点: 由于第一个数据结点位置被存放在头结点指针域中,所以链表第一个位置上操作和在表其他位置上操作一致,无需进行特殊处理。...为了克服单链表上述缺点,引入了链表链表结点中有两个指针 prior 和 next,分别指向其前驱结点和后继结点。...= self.next = None # 前驱和后继指针 链表链表结点中增加了一个指向其前驱 prior 指针,因此链表按值查找和按位查找操作与单链表相同,但链表插入和删除操作实现上...循环链表 循环单链表 ? 循环单链表,表尾结点 r next 域指向 L,故表没有指针域为 None 结点,因此,循环单链表判空条件不是头结点指针是否为空,而是它是否等于头指针。...循环链表 由循环单链表定义不难推出循环链表。不同循环链表,头结点 prior 指针还要指向表尾结点,如图所示。 ?

    88310

    前端学数据结构与算法(四):理解递归及拿力扣链表题目练手

    再解决链表问题时,如果没有思路,可以用纸和笔把指针指向过程画下来,然后再尝试从里面找到重复子问题会很有帮助。 206....两两交换链表节点↓ 给定一个链表,两两交换其中相邻节点,并返回交换链表。 你不能只是单纯改变节点内部值,而是需要实际进行节点交换。...如果尝试用纸和笔画出过程,就很容易发现子问题,让第一个节点指向第二个节点之后已经交换链表,然后让第二个节点指向之前节点。...1->2->3->4->5 返回3->4->5 设置两个指针,慢指针一次走一步,快指针一次走两步,当快指针走完时,正好慢指针链表中间。...环形链表↓ 给定一个链表,判断链表是否有环。 为了表示给定链表环,我们使用整数 pos 来表示链表尾连接到链表位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表没有环。

    58300

    文心一言 VS 讯飞星火 VS chatgpt (157)-- 算法导论12.3 4题

    文心一言: Go语言中,删除操作是不可交换。这意味着先删除节点 x 再删除节点 y 与先删除节点 y 再删除节点 x 留下结果树可能不同。...在这里插入图片描述 智谱清言: Go语言中,删除操作大多数数据结构是不可交换,因为删除操作通常依赖于元素索引或位置。...让我们举一个反例来说明删除操作Go语言中不可交换性: 假设我们有一个整数切片 [1, 2, 3, 4, 5],我们将尝试删除元素 2 和 3。...切片:删除操作也不是可交换,原因与数组相同。 3. 链表:对于链表,删除操作通常是可交换。因为链表每个节点都有一个指向下一个节点指针,所以删除操作只会影响被删除节点和其相邻节点。...在这里插入图片描述 天工: Go语言中,删除操作不可交换。原因如下: 假设我们有两个有序元素x和y,我们想要删除x和y。 1.

    13520

    【递归、搜索与回溯算法练习】day2

    两两交换链表节点 1.题目简介 24. 两两交换链表节点 给你一个链表,两两交换其中相邻节点,并返回交换链表节点。...你必须在不修改节点内部情况下完成本题(即,只能进行节点交换)。...2.解题思路 递归思路: 先处理第二个节点之后节点,再将前两个节点进行交换,最后连接后面处理好节点 迭代思路: 指针法(三指针法) 两个指针进行交换,第三个指针进行遍历,直到将链表遍历结束...cur = head -> next,* next = cur -> next; ListNode* newhead = cur; int flag = 1;//假设链表节点个数为偶数...while(next) { cur -> next = prev; if(next -> next)//链表节点个数是偶数个或者未到达链表结尾

    12310

    Leetcode链表题目总结

    注意: 如果两个链表没有交点,返回 null 。 返回结果后,两个链表仍须保持原有的结构。 可假定整个链表结构没有循环。 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。...题目描述   给定一个链表,两两交换其中相邻节点,并返回交换链表。...解题思路   本题需要两两交换链表相邻节点,这说明在在整个过程中都是功能相同操作,这让我们就很自然想到使用递归方式去处理。...两个链表第一个公共节点 题目描述   输入两个链表,找出它们第一个公共节点。   如下面的两个链表: ?   节点 c1 开始相交。 示例 1: ?...注意: 如果两个链表没有交点,返回 null. 返回结果后,两个链表仍须保持原有的结构。 可假定整个链表结构没有循环。 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

    57620

    写给前端算法进阶指南,我是如何两个月零基础刷200题

    分类大纲 算法复杂度分析。 排序算法,以及他们区别和优化。 数组指针、滑动窗口思想。 利用 Map 和 Set 处理查找表问题。 链表各种问题。 利用递归和迭代法解决二叉树问题。...---- 先按照升序排序,然后分别从左往右依次选择一个基础点 i(0 <= i <= nums.length - 3),基础点右侧用指针去不断找最小差值。...在此基础上,先尝试取窗口右边界再右边一个位置值,也就是 str[right + 1],然后拿这个值去 freqMap 查找: 这个值没有出现过,那就直接把 right ++,扩大窗口右边界。...两两交换链表节点-24 给定一个链表,两两交换其中相邻节点,并返回交换链表。...说明: 叶子节点是指没有节点节点

    90410

    TypeScript算法题实战——链表篇(链表设计、反转、两两交换、删除、相交和环形链表

    链表是一种通过指针串联在一起线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点指针),最后一个节点指针域指向null(空指针意思),链表类型有单链表链表、循环链表...您可以选择使用单链表链表。单链表节点应该具有两个属性:val 和 next。val 是当前节点值,next 是指向下一个节点指针/引用。...链表实现这些功能:get(index):获取链表第 index 个节点值。如果索引无效,则返回-1。addAtHead(val):链表第一个元素之前添加一个值为 val 节点。...5.1、题目描述力扣链接:https://leetcode.cn/problems/swap-nodes-in-pairs/给你一个链表,两两交换其中相邻节点,并返回交换链表节点。...如果两个链表没有交点,返回 null 。

    14310
    领券