【4.21 代随_03day】链表part01


链表理论基础

  链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。

  • 单链表
    在这里插入图片描述
  • 双链表
    在这里插入图片描述
  • 循环链表(可以用来解决约瑟夫环问题。)
    在这里插入图片描述
    总结:
      链表中的节点在内存中不是连续分布的 ,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理

移除链表元素

力扣连接:203.移除链表元素(简单)

在这里插入图片描述

使用java ,python的话就不用手动管理内存

这里就涉及如下链表操作的两种方式:

  • 直接使用原来的链表来进行删除操作。
  • 设置一个虚拟头结点在进行删除操作。

1.代码

//不用额外的结点
public ListNode removeElements(ListNode head, int val) {
	
	//删除头结点
	while(head!=null&&head.val==val){
		head = head.next;
	}

	ListNode res = head;
	//删除非头结点
	while(res!=null){
		while(res.next!=null&&res.next.val==val){
			res.next = res.next.next;
			}
		res = res.next;
	}

	return head;
}


设计链表

力扣连接:707.设计链表(中等)

设置一个虚拟头结点(这样更方便一些)

代码

class ListNode {
    Integer val;
    ListNode next;

    public ListNode(){}
    public ListNode(Integer val){this.val = val;}
    public ListNode(Integer val, ListNode next){
        this.val = val;
        this.next = next;
    }
}

class MyLinkedList {

    ListNode node;
    Integer len;

    public MyLinkedList() {
        node = new ListNode(-1);
        len = 0;
    }
    
    public int get(int index) {
        //越界情况
        if(index>=len || index<0) return -1;

        ListNode p = findPrev(index);

        return p.next.val;
    }
    
    public void addAtHead(int val) {
        addAtIndex(0,val);
    }
    
    public void addAtTail(int val) {
        addAtIndex(len,val);
    }
    
    public void addAtIndex(int index, int val) {
        //越界情况
        if(index>len) return;
        if(index<0) index = 0;

        //找前驱
        ListNode p = findPrev(index);
        ListNode gen = new ListNode(val);

        //插入前驱后
        gen.next = p.next;
        p.next = gen;

        len++;

    }
    
    public void deleteAtIndex(int index) {
        //越界情况
        if(index>=len || index<0) return;

        ListNode p = findPrev(index);
        p.next = p.next.next;

        len--;
    }

    //获取前驱结点
    public ListNode findPrev(int index){
        ListNode prev = node;
        for(int i = 0;i<index;i++){
            prev = prev.next;
        }
        return prev;
    }
}

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList obj = new MyLinkedList();
 * int param_1 = obj.get(index);
 * obj.addAtHead(val);
 * obj.addAtTail(val);
 * obj.addAtIndex(index,val);
 * obj.deleteAtIndex(index);
 */


反转链表

力扣连接:206. 反转链表(简单)

在这里插入图片描述

1.代码(双指针法)

public ListNode reverseList(ListNode head) {
	if(head==null) return null;
        
	ListNode prev = null;
	ListNode front = head;

	while(front!=null){
		//保存front的下一个结点
		ListNode temp = front.next;
            
		//front的下一个结点指向prev
		front.next = prev;

		//prev指针向前
		prev = front;

		//front指针向前
		front = temp;
	}

	return prev;
}

注意

  • 首先要把 cur->next 节点用tmp指针保存一下。

2.代码(递归法)

public ListNode reverseList(ListNode head) {
	return reverse(null, head);
}

private ListNode reverse(ListNode prev, ListNode cur) {
	if (cur == null) {
		return prev;
	}
	ListNode temp = null;
	temp = cur.next;// 先保存下一个节点
	cur.next = prev;// 反转
	// 更新prev、cur位置
	// prev = cur;
	// cur = temp;
	return reverse(cur, temp);
}

总结

这一次学习了链表的相关知识,了解了链表的增删查

一般建立一个新的结点指向头结点会比在原链表上操作容易一些。

判断是否为null的对象一般是跟随执行内容改变

if(prev!=null){
	prev=prev.next;
}

if(prev.next!=null){
	prev.next=prev.next.next;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值