什么?哨兵位竟这么简单......

这里呢就用一道题来解释什么叫做哨兵位,以及哨兵位应该怎么使用

链接请点这边☛☛☛☛牛客CM11
在这里插入图片描述

方法一:

将链表中的元素进行遍历,当这个链表中有小于x的数时,将这个位置的数据头插到链表,销毁此位置,然后链表继续向后走。不建议此方法,中途涉及保存当前位置,头位置等的问题,很麻烦!!(感兴趣可以自写代码尝试)

方法二:

将链表中的数据按顺序存到一个数组当中,然后按题目要求排序,再将值放回到原链表中,此方法的较为稳妥,可以尝试。

方法三(哨兵位):

分别开辟两个结构体来当小头链表和大头链表,将小于x的节点存到小头,其他节点存到大头,然后让小头的尾与大头的头连接到一起,返回小头的地址即可。(此方法非常适合用于此类题型,十分建议!!)
下面是AC代码演示及说明。

p1表示小链表,p11表示小链表头节点的拷贝
p2表示大链表,p22表示大链表头节点的拷贝

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        ListNode* p1, *p11, *p2, *p22;
        ListNode* cur = pHead; 
        p1 = (ListNode*)malloc(sizeof(ListNode));
        p11 = p1;
        p2 = (ListNode*)malloc(sizeof(ListNode));
        p22 = p2;
        while(cur)
        {
            if(cur->val < x)
            {
                p1->next = cur;//小链表赋值
                p1 = p1->next;//小链表向下走
            }
            else
            {
                p2->next = cur;//大链表进行赋值
                p2 = p2->next; //大链表向下走
            }
            cur = cur->next;//原链表向下走
        }
        p2->next = NULL;//大链表后面无需连其他节点,让他不再向后连,进行置空
        p1->next = p22->next;//小链表的尾连在大链表的第一个头,这边注意是开的是哨兵位,所以第一个节点不保存它的数据,所以要让他连在第二个的位置,这样整个链表就连在一起了
        pHead = p11->next;//同样这边需要将这个头指向这个链表的第二个位置
        free(p11);//释放两个malloc的哨兵位,释放堆空间
        free(p22);

        return pHead;
    }
};

从上述的代码中,我们说明了两个问题。

首先什么是哨兵位,可以看到,我们方法三的思路就是将这个数据分别存在两个链表中,这两个链表的头不会存数据,只是起到连接的作用,那么这样的头就是哨兵位的头,只起到连接作用,而不存放数据,函数结束还需要将这个哨兵位的头进行free操作。

第二个问题就是代码中的biglist->next = NULL,这句的作用在于,当这个链表在结束后,对于小链表的尾是指向大链表的头,而大链表的尾还是指向的是原来的数,所以就要对他指向的next进行置空的操作,否则有可能能会造成死循环的现象。

画图演示死循环如图
死循环现象

所以要将大链表的尾的next置为NULL。

觉得有用可以分享给小伙伴,欢迎一起来交流~~
请添加图片描述

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温有情

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值