当前位置: 首页 > article >正文

单链表---链表分割

将小于x的结点放在前面,大于等于x的结点放在后面,不改变结点相对位置,输出更改后的链表首结点。

typedef struct ListNode
{
    ListNode* next;
    int val;
}ListNode;

思路:我们可以新创建两个链表指针,将小于x的结点全部链接到链表1,大于等于x的结点全部链接到链表2,然后将链表1尾结点链接链表2头结点。

方法一---不使用哨兵位

    ListNode* cur = pHead;
    ListNode* head1 = NULL;
    ListNode* cur1 = head1;
    ListNode* head2 = NULL;
    ListNode* cur2 = head2;

当我们不使用哨兵位的时候,意味着,两个链表某一个为NULL的情况都属于特殊情况,不能解引用非法访问,因此在分割完的链接过程需要对cur1与cur2进行单独条件判断是否为空 。

当cur1为空说明了分割使所有结点都在链表2,那么cur2肯定不为空,因此将链表2尾结点存储的next置空然后返回链表2指针head2即可;cur1不为空,那么判断cur2是否为空,cur2为空则将链表1尾结点存储的next置空然后返回链表1指针head1即可,cur2不为空则正常链接两个链表然后将链表2尾结点存储的next置空,返回head1。

    while (cur)
    {
        if (cur->val < x)
        {
            if (cur1 == NULL)
            {
                head1 = cur;
                cur1 = cur;
            }
            else
            {
                cur1->next = cur;
                cur1 = cur1->next;
            }
        }
        else
        {
            if (cur2 == NULL)
            {
                head2 = cur;
                cur2 = cur;
            }
            else
            {
                cur2->next = cur;
                cur2 = cur2->next;
            }
        }
        cur = cur->next;
    }

我们遍历原链表,然后进行结点的分配,由于没有哨兵位,我们需要对两个链表是否为空进行额外的判断如下:

    if (cur1)
    {
        if (cur2)
        {
            cur2->next = NULL;
        }
        cur1->next = head2;
        return head1;
    }
    else
    {
        cur2->next = NULL;
        return head2;
    }

方法二---创建哨兵位

哨兵位的创建能够减少额外的判断,例如方法一中对两个链表指针是否为NULL的判断,由于哨兵位本身存在,所以head1与head2是不可能为NULL的,head1->next与head2->next才指向了真正有效的结点。那么我们就malloc两块结点空间作为两个哨兵位,然后进行操作:

    ListNode* head1, * cur1, * head2, * cur2;
    head1 = cur1 = (ListNode*)malloc(sizeof(ListNode));
    head2 = cur2 = (ListNode*)malloc(sizeof(ListNode));
    ListNode* cur = pHead;

一般而言malloc开辟,需要判断是否开辟成功,请注意,同时最后需要释放空间,避免内存泄漏。

那么cur的遍历过程就会简单很多,不需要判断head1与head2是否为空了。

    while (cur)
    {
        if (cur->val < x)
        {
            cur1->next = cur;
            cur1 = cur1->next;
        }
        else
        {
            cur2->next = cur;
            cur2 = cur2->next;
        }
        cur = cur->next;
    }

然后链表1尾结点next链接链表2头结点head2->next,(不是head2,head2是哨兵位!)

最后将cur2->next置空。

但是,哨兵位的方法,最终需要释放空间,因此我们需要先将需要返回的head1->next赋给我们的一个指针变量tmp,然后free掉head1与head2,返回tmp:

    ListNode* tmp = head1->next;
    free(head1);
    free(head2);
    return tmp;


http://www.kler.cn/a/420368.html

相关文章:

  • java将word docx pdf转换为图片(不需要额外下载压缩包,直接导入maven坐标)
  • 【Linux】应用层协议—HTTP
  • 【AI系统】昇腾异构计算架构 CANN
  • 使用CertD全自动申请和部署SSL证书至服务器
  • 【系统架构设计师】真题论文: 论软件质量保证及其应用(包括解题思路和素材)
  • 在树莓派上使用自带的摄像头采集视频
  • 基于米尔全志T527开发板的FacenetPytorch人脸识别方案
  • 【C++】深入解析 using namespace std 语句
  • npm error code ETIMEDOUT 简单排查
  • 双向长短期记忆(Bi-LSTM)神经网络介绍
  • Linux - 前端程序员常用的 Linux 命令
  • LearnOpenGL学习(光照 -- 投光物,多光源)
  • 在云上怎么样让环境更加安全?
  • SQLAlchemy
  • Spring,SpringMVC,SpringBoot,SpringCloud有什么区别和联系?
  • 汽车操作系统详解
  • dhcpd服务器的配置与管理(超详细!!!)
  • 贝叶斯统计的核心思想与基础知识:中英双语
  • 含k个3的数
  • 产品转后端?
  • 使用 Docker 部署 Spring Boot 项目流程
  • STM32 ADC --- 多通道序列采样
  • 应对智能时代——读《人工智能时代的生存指南》
  • TP6 html生成ptf并加盖骑缝章
  • 运输层2——UDP协议
  • liteflow 架构详解