【Java数据结构与算法】链表

🔣单链表反转
题目:给你一个单链表,将这个链表反转输出
示例:
输入:①->②->③->④->⑤->⑥->⑦->null;
输出:⑦->⑥->⑤->④->③->②->①->null;
思路:
定义pre,next等于null,一开始head指向节点①,要让他逆序输出。我先记录节点②,next=head.next,此时next就是节点②,然后我让head.next=pre,此时节点①的指针指向空(也就是pre),pre来到head的位置,也就是pre从null来到节点①的位置 ,head往下走,来到next,所以head=next
code:

public static ListNode reverseList(ListNode head) {
    ListNode pre=null;
	ListNode next=null;
	while(head!=null){
    //next记录head.next的位置,也就是节点②
    next=head.next;
    //让head.next指向pre也就是空,也就是让节点①的位置指向null
    head.next=pre;
    //然后pre来到head的位置,也就是pre从null来到节点①的位置
    pre=head;
    //head来到next的位置,也就是head从节点①来到了节点②的位置
    head=next;
	}
	//最后返回pre(pre走的最慢,next走的最快,一直在记录head节点的下一个位置(也就是head.next的位置)
	return pre;
}

🔣双链表的反转
题目:给你一个双链表,将这个链表反转输出
示例:
输入: ①-> ②-> ③->④-> ⑤-> ⑥->⑦->null;
null<①<②<③<④<⑤<⑥<~⑦
输出:⑦->⑥->⑤->④->③->②->①->null;
null<⑦<⑥<⑤<④<③<②<~①
思路:
我们先理解->为next,~>为last指针。定义pre,next等于null,一开始head指向节点①,要让他逆序输出。我先记录节点②,next=head.next,此时next就是节点②,然后我让head.next=pre,此时节点①的指针指向空(也就是pre),我让head.last指针指向next,也就是节点①的last指针指向节点②,pre来到head的位置,也就是pre从null来到节点①的位置,head往下走,来到next的位置,也就是head从节点①走到节点②
code:

public static ListNode reverseDoubleList(ListNode head) {
	ListNode pre=null;
	ListNode next=null;
	while(head!=null){
        next=head.next;
        head.next=pre;
        head.last=next;
        pre=head;
        head=next;
    }
return pre;
}

🔣用单链表结构实现队列
首先我们要知道什么是队列,队列,顾名思义就和排队一样,先进先出,就比如排队做核酸,我先来的我排前面,你们后来的排后面,做完核酸我先走,从而队列就是先进先出。拓展 队列分单端队列(Queue)和双端队列(Deque)。
思路:
第一步:先入队(添加push),我先创建一个节点cur,如果我的尾巴tail为空,我就让head和tail都指向cur,否则尾巴的指针指向新进来的节点,tail.next=cur;尾巴来到新节点,tail=cur;每新建一个节点我的长度size++
第二步:出队(弹出poll),用一个变量答案ans为null,如果我的头节点不为空 ,ans就等于头节点的值,头节点往下移动,然后长度size–
code:

//添加
public static ListNode push(ListNode Node) {
    Node<ListNode> cur = new Node<>();
if (tail == null) {
    head = cur;
    tail = cur;
} else {
    tail.next = cur;
    tail = node;
}
size++;
}

//弹出
public static ListNode poll() {
    ListNode ans = null;
    if (head != null) {
        ans = head.value;
        head = head.next;
        size--;
    }
    if (head == null) {
        tail = null;
    }
    return ans;
}

🔣用单链表结构实现栈
首先我们要知道什么是栈,栈和队列的区别就是,栈是先进后出,和弹夹一样,像中国军人拆解国产95式弹夹视频想必大家都看过把,先把子弹压到最下面,射出子弹是先射出上面的子弹,所以栈结构就是弹夹。
思路:
第一步:先入栈(压栈push),我先创建一个节点cur,如果我的头head为空,我就让head等于cur,否则让新节点的指针指向head,head=cur;每新建一个节点我的长度size++
第二步:出栈(弹出pop),用一个变量答案ans为null,如果我的头节点不为空 ,ans就等于头节点的值,头节点往下移动,然后长度size–
code:

//压栈
public static ListNode push(ListNode Node) {
    Node<ListNode> cur = new Node<>();
if (head== null) {
    head = cur;
} else {
    cur.next=head;
    head=cur;
}
size++;
}

//弹出
public static ListNode pop() {
    ListNode ans = null;
    if (head != null) {
        ans = head.value;
        head = head.next;
        size--;
    }

    return ans;
}

🔣用双链表转为双端队列
首先我们讲讲什么是双端队列,就是头能进,头也能出,尾能进,尾也能出,这个是单链表完成不了的,就是不能从头出。
code:

public static ListNode headpush(ListNode Node) {
    Node<ListNode> cur = new Node<>();
if (head== null) {
    head = cur;
    tail=null;
} else {
    cur.next=head;
    head.last=cur;
    head=cur;
}
size++;
}
//尾进
public static ListNode tailpush(ListNode Node) {
    Node<ListNode> cur = new Node<>();
if (head== null) {
    head = cur;
    tail=null;
} else {
    tail.next=cur;
    cur.last=tail;
    tail=cur;
}
size++;
}

//头出
public static ListNode headpop() {
    ListNode ans = null;
    if(head==null){
        return ans;
    }
    size--;
    ans=head.value;
    if (head == tail) {
        tail=null;
        head=null;
    }else{
        head=head.next;
        head.last=null;
    }

    return ans;
}
//尾出
public static ListNode tailpop() {
    ListNode ans = null;
    if(head==null){
        return ans;
    }
    size--;
    ans=head.value;
    if (head == tail) {
        tail=null;
        head=null;
    }else{
        tail=tail.last;
        tail.next=null;
    }
    return ans;
}

🔣K 个一组翻转链表
题目链接:https://leetcode.cn/problems/reverse-nodes-in-k-group/** **
code:

public static ListNode reverseKGroup(ListNode head, int k) {
        ListNode start = head;
        ListNode end = getKGroupEnd(start, k);
        if (end == null) {
            return head;
        }
        // 第一组凑齐了!
        head = end;
        reverse(start, end);
        // 上一组的结尾节点
        ListNode lastEnd = start;
        while (lastEnd.next != null) {
            start = lastEnd.next;
            end = getKGroupEnd(start, k);
            if (end == null) {
                return head;
            }
            reverse(start, end);
            lastEnd.next = end;
            lastEnd = start;
        }
        return head;
    }


    public static ListNode getKGroupEnd(ListNode start, int k) {
        while (--k != 0 && start != null) {
            start = start.next;
        }
        return start;
    }


    public static void reverse(ListNode start, ListNode end) {
        end = end.next;
        ListNode pre = null;
        ListNode cur = start;
        ListNode next = null;
        while (cur != end) {
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        start.next = end;
    }

🔣合并排序链表(两个链表有序)
题目链接:https://leetcode.cn/problems/vvXgSW/
思路:
第一步:考虑边界条件,如果两个链表中有其中一个为空,我不需要合。
第二步:谁小谁做头节点,cur1指向小头下一个节点,cur2直接指向大头
第三步:①长链表有元素,短链表有元素。②长链表有元素,短链表没有元素③长链表短链表都没有元素。
code:

public static ListNode lists(ListNode head1, ListNode head2) {
    if (head1 == null || head2 == null) {
        return head1 == null ? head2 : head1;
    }
    //谁小谁做头节点
    ListNode head = head1.value <=head2.value? head1 : head2;
    //小的头节点下一个,叫做cur1,也就是第二个节点
    ListNode cur1 = head.next;
    //大头的第一个叫cur2,如果head1为小头,那么head2就是cur2
    ListNode cur2 = head == head1 ? head2 : head1;
    //准备好一个pre,因为head锁死了
    ListNode pre = head;
    while (cur1 != null && cur2 != null) {
        //15-20行代码 谁小谁让pre.next指上,谁小谁往下动
        if (cur1.value <= cur2.value) {
            pre.next = cur1;
            cur1 = cur1.next;
        } else {
            pre.next = cur1;
            cur2 = cur2.next;
        }
        //pre往下走
        pre = pre.next;
    }
    pre.next = cur1 != null ? cur1 : cur2;
    return head;
}

🔣两个链表相加
题目:给你两个个单链表,将这个链表相加输出
示例:
输入:①->②->③->④->null;⑤->⑥->⑦->⑧->null;
输出:⑥->⑧->〇->③->①->null;
解释:4321+8765=13086
code:

public static ListNode addTwoNumbers(ListNode head1, ListNode head2) {
    int len1 = listLength(head1);
    int len2 = listLength(head2);

    //长链表为L,短链表为S
    ListNode L = len1 >= len2 ? head1 : head2;
    ListNode S = L == head1 ? head2 : head1;
    //长链表的当前节点
    ListNode curL = L;
    //短链表的当前节点
    ListNode curS = S;
    //last就是幽灵跟踪curL,就是长链表最后一个不空的节点
    ListNode last = curL;
    //要提前准备进位信息carry
    int carry = 0;
    //和 相当于长链表+短链表之后的值
    int curNum = 0;
    while (curS != null) {//长链表还有元素,短链表也有
        curNum = curL.value + curS.value + carry;
        curL.value = (curNum % 10);
        carry = curNum / 10;
        last = curL;
        //长,短链表同时往下走
        curL = curL.next;
        curS = curS.next;
    }

    while (curL != null) {//长链表有元素,短链表没有元素
        curNum = curL.value + carry;
        curL.value = curNum % 10;
        carry = curNum / 10;
        last = curL;
        curL = curL.next;
    }
    if (carry != 0) {//长链表没有元素,短链表也没有元素
        last.next = new ListNode(1);
    }
    return L;
}

//求链表长度
public static int listLength(ListNode head) {
    int len = 0;
while (head != null) {
    len++;
    head = head.next;
}
return len;
}

创作不易,如果教练们觉得有用别忘记三连啊哈在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

凇:)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值