编程技巧 - 哨兵 在 链表 和 数组 中的使用及解析

——示例1链表:

方便链表中的对于特殊结点的操作,简化判断一个结点是否为空,下例为对单例表中向末尾插入
     哨兵结点(sentinel):
            可以简化边界条件,降低实现难度,它并不存储任何东西,只是为了操作的方便而引入的。
            在链表中的插入、删除操作,需要对插入第一个结点和删除最后一个结点进行特殊处理,
            比如插入时判断head结点是否null,使用哨兵结点后可以最大限度减少这种判断。

    1.不使用哨兵
    private Node head=null; //头结点
    //插入
    public void insert(Node node){
        if(head==null)
            head=node;
        Node tmpHead=head;
        while(tmpHead.next!=null){
            tmpHead=tmpHead.next;
        }
        tmpHead.next=node;
    }

    2.使用哨兵结点
    private final Node sentry = new Node();   //哨兵结点
    private Node head = sentry; //**头结点指向哨兵结点,这样链表就不会为空了,
    //插入
    public void insert(Node node){
        Node tmpHead=head;
        while(tmpHead.next!=null){
            tmpHead=tmpHead.next;
        }
        tmpHead.next=node;
    }

    使用哨兵结点后,可以用统一的代码进行实现,无论是不是第一个结点或者其他结点 ,减少链表对第一个元素是否为空的判断
    同样,哨兵结点也可以放在最后 来简化删除最后一个结点的特殊处理


——示例2数组

尾部哨兵 如果要在含n个数的数组array中找个数value
    1.普通写法:
        for (int i = 0; i < n; ++i) {
            if (value == array[i])
                return i;
        }
    2.使用哨兵:
        array[n] = value;
        for (int i = 0;; i++) {
            if (value == array[i]) {
                if (i != n)
                    return i;
            }
        }
    假设n为9,array[8]为value,也就是数组中的最后一个元素是我们要找的数,

    普通写法
       int i=0  执行1次
       i<n      执行9次
       ++i      执行8次
       if (value == array[i])   执行9次
       return i    执行1次
       假设每个操作消耗的时间单元是一样的,那么普通写法一共消耗了28个时间单元

    使用哨兵
        array[n] = value;   执行1次
        int i = 0   执行1次
        i++         执行8次
        if (value == array[i])    执行9次
        if (i != n) 执行1次
        return i    执行1次

    使用哨兵一共消耗了21个时间单元,可以看使用哨兵比普通写法节省了每次 i<n 的耗时,而这个消耗会随着n的增大而增大
    刚才是要找的元素在数组中,如果不在数组中,使用哨兵也不会出现异常,因为原数组的末尾添加了我们要找的数字,一定会有value==array[i]时
    判断该数字是否是我们手动添加的数字,也就是if (i != n),i==n即为我们手动添加的数字,若i!=n,则提前找到了value 该位置即为所求。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值