【指针学习与回顾】学习java后天天学框架,不用指针,一刷leetcode还是要回顾指针

个人学习回顾,欢迎学习交流。

java中有大量已经封装好的链表,例如:LinkedList、LinkedHashSet等等,当我经常使用这些封装类后,我对指针操作就愈来愈不敏感,导致刷leetcode时,关于指针操作的题总是摸不着头脑。所以即使在学java,python,我们仍然要对指针有较好的掌握。

一、指针与地址

1、指针和地址最大的区别就是指针是有类型的,地址是没有类型的。我们当然可以通过绝对地址的方式找到函数和数据,但是地址是没有类型的,不能对地址进行算术操作,在涉及诸如数组等操作时就不能通过地址的自增和自减来访问数组的各个变量。
2、指针是由地址和类型两部分构成的,指向数据的指针不仅记录该数据的在内存中的存放的地址,还记录该数据的类型,即在内存中占用几个字节,这是地址所不具有的。

简单来说,我们使用的指针实际上是用来保存或着说是指向地址空间的。指针更像是地址空间的导航标识,它会告诉我们的数据存放的地址以及该数据的数据类型。

二、指针与链表

说到链表我们就不能不想到指针,两者就是一体的。且链表是有序的。

我们初学时都常学到的链表有两大类,即单链表和双链表。

单链表就是只有后继没有前驱,即只有指向下一个元素节点的指针,没有指向上一个元素节点的指针。

双链表就是既有前驱也有后继。

三、个人对指针的理解

当我们对地址操作时,即修改指针时,实际是操作当前指针的变化改变地址之间的结构,所以无论我们是对 指针1 本身操作,还是将 指针1 赋值给另一个 指针2 ,然后操作 指针2 。这两种情况都是在操作同一个地址,都会改变了地址结构。但值得注意的是,我们将 指针1 赋值给另一个 指针2时,然后操作 指针2,我们是改变了 指针1 所指向的地址结构,但却没有改变 指针1 ,即 指针1 不会因 指针2 的改变而发生改变。

四、例题举例

剑指 Offer 18. 删除链表的节点

题解:

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。

示例 1:

输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.

解法:

只需注意一点,在赋值时,因为这是一个链表所以head是一个地址,我们将head赋值给tmpNode时,当我们对地址操作时,实际是操作当前指针的变化,所以tmpNode和cache的变化也会改变head所属链表的结构变化,但我们有没有改变head头指针所以,头指针不发生变化,变化的只是链表结构。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode deleteNode(ListNode head, int val) {
        ListNode tmpNode = head,cache = head.next;
        if (head.val == val){
            head = head.next;
            return head;
        }
        while(cache != null && cache.val != val){
            tmpNode = cache;
            cache = cache.next;
        }
        if (cache != null){
            tmpNode.next = cache.next;
        }
        return head;
    }
}

也有另一种方法,就是设置哑节点。哑节点的主要目的是让链表中的每一个节点都有前驱,这样我们在操作时就无需过多考虑特殊情况。

class Solution {
    public ListNode deleteNode(ListNode head, int val) {
        ListNode temp = new ListNode(0);
        temp.next = head;
        head = temp;
        while(temp.next!=null){
            if(temp.next.val==val){
                temp.next = temp.next.next;
                return head.next;
            }
            temp = temp.next;
        }
        return head.next;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值