文章结构

  1. 链表的概念/用处
  2. 链表的基本代码实现(韩顺平Java数据结构网课)
  3. 剑指offer上链表题目代码实现(个人手敲,更精巧的答案可以参考官网)

链表

链表包含单链表,双向链表,循环链表等等。相对于线性表,添加,删除操作非常方便,因为不用移动大量的节点,只需要修改对应的前后节点指针即可。下面用一个具体实例来说明下这种结构。现在有一需求,是将具有不同编号,姓名,昵称的人添加到系统中。首先需要创建节点,既然是链表,节点除了基本信息也要加入下一节点指针,方便计算机在内存中查找。

单向链表是通过指针构建的列表,基本结构就是头节点+下一节点地址指针--->节点+下一节点地址指针--->尾节点。

单链表的基本代码实现

在这里强推一波韩顺平的Java数据结构网课,讲的由浅入深,笔记详细。当然自己看视频之后自己再写才是正道。

https://www.bilibili.com/video/av54029771?from=search&seid=15096936792873170656​www.bilibili.com

class HeroNode{public int no; //编号public String name; //姓名public String nickname;//昵称public HeroNode next; //下一节点指针//构造器public HeroNode(int no, String name, String nickname) {this.no = no;this.name = name;this.nickname = nickname;     }@Overridepublic String toString() {return "HeroNode [no = " + no + ", name " + name + ", nickname = " + nickname;}}

下一步是创建链表类,包括一些基本操作方法

class SingleLinkedList{//初始化头节点,头节点不动private HeroNode head = new HeroNode(0, "", "");//返回头节点,方便后续操作public HeroNode getHead() {return head;}//添加节点内到单向链表//思路,当不考虑编号顺序,找到当前链表的最后节点,将最后节点的next指向新节点public void add(HeroNode heroNode) {HeroNode temp = head;//遍历链表,找到最后while(true) {if(temp.next == null) {break;}//如果没有找到,将temp后移temp = temp.next;}temp.next = heroNode;}//按照顺序添加public void addByOrder(HeroNode heroNode) {//头节点不能动,通过辅助指针//单链表,因此temp在添加位置的前一个结点HeroNode temp = head;boolean flag = false; //编号是否存在while(true) {if(temp.next == null) {//链表最后break;}if(temp.next.no > heroNode.no) {//位置找到break;}else if(temp.next.no == heroNode.no){//编号存在flag = true;      }temp = temp.next;}if(flag) {System.out.printf("编号%d存在", heroNode.no);}else {heroNode.next = temp.next;temp.next = heroNode;}}//更新链表,在找到序号的情况下进行更新public void update(HeroNode newHeroNode) {//根据no修改if(head.next == null) {System.out.println("链表为空");return;}HeroNode temp = head.next;boolean flag = false;while(true) {if(temp == null) {break;}if(temp.no == newHeroNode.no) {flag = true;break;}temp = temp.next;}if(flag) {temp.name = newHeroNode.name;temp.nickname = newHeroNode.nickname;}else {System.out.printf("没找编号%d的值", newHeroNode.no);}}//删除节点//head不动,找到被删除节点的前一个public void del(int no) {HeroNode temp = head;boolean flag = false;while(true) {if(temp.next == null) {break;}if (temp.next.no == no) {flag = true;break;}temp = temp.next;}if(flag) {temp.next = temp.next.next;}else {System.out.printf("要删除的节点%d不存在", no);}}   }

这里说下头节点存在的意义:

1.防止单链表是空的而设的,否则空链表头指针就会指向null.

2.方便插入表头或者删除第一个结点

剑指offer涉及到的链表题目

第一题:从尾到头打印链表

思路:递归,深入到最底层取出节点.val值后一层一层回退

import java.util.ArrayList;
public class Solution {ArrayList<Integer> list = new ArrayList<Integer>();public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {if(listNode != null){this.printListFromTailToHead(listNode.next);list.add(listNode.val);}return list;}
}

第二题:输入一个链表,输出该链表中倒数第k个结点。

思路1 传统法得到链表长度L,再从头遍历到L-k个

思路2 快慢指针,慢指针距离快指针始终k,当快指针到最后的null时候,输出慢指针

代码是思路2

public class Solution {public ListNode FindKthToTail(ListNode head,int k) {//快慢指针ListNode fast = head;ListNode slow = head;for(int i = 0; i < k; i++){if(fast == null){return null;}       fast = fast.next;}while(fast != null){fast = fast.next;slow = slow.next;}return slow;}
}

第三题:输入一个链表,反转链表后,输出新链表的表头。

思路:本能反应是遍历到最后,倒数第二,第三以此类推,但是这样每次都遍历一遍链表花销太大。最清真的思路是采用头插法,先建立一个新的头节点,依次将链表中的节点插入到新头节点后边的第一个位置,以此类推。这里需要注意的是为了防止断链,要建立额外指针来储存当前插入点current在原链表的下一个节点。

题外话:韩老师的视频里面头节点是没有数据的,这个题目Head是有数据的,害得我提交很多次都不合格。下面这个是head无数据版本

public class Solution {public ListNode ReverseList(ListNode head) {if(head.next == null || head.next.next == null) {return head;}//辅助指针,遍历原来的链表ListNode cur = head.next.next;ListNode next = null; //指向cur的下一个节点 防止断链ListNode reverseHead = null;while( cur != null) {next = cur.next;//暂时保存后面有用cur.next = reverseHead.next;//cur的下一个节点指向新链表的最前端reverseHead.next = cur;//cur连接到新的链表最顶端cur = next;}return reverseHead;}
}

下面这个是head有数据版本

public class Solution {public ListNode ReverseList(ListNode head) {if(head==null)return null;ListNode pre = null;ListNode next = null;while(head!=null){next = head.next;head.next = pre;pre = head;head = next;}return pre;}
}

第四题:合并两个有序链表

/*
public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}
}*/
public class Solution {public ListNode Merge(ListNode list1, ListNode list2) {if (list1 == null) {return list2;}if (list2 == null) {return list1;}ListNode temp = null;ListNode mergeHead = null;while (list1 != null && list2 != null) {if (list1.val < list2.val) {if (mergeHead == null) {mergeHead = list1;temp = list1;} else {temp.next = list1;temp = temp.next;}list1 = list1.next;} else {if (mergeHead == null) {mergeHead = list2;temp = list2;} else {temp.next = list2;temp = temp.next;}list2 = list2.next;}}if (list1 == null) {temp.next = list2;} else {temp.next = list1;}return mergeHead;}
}

java单链表节点翻转_Java数据结构01-链表基础(讲解+代码+面试题)相关推荐

  1. Java实现自定义队列和树结构_Java数据结构之链表、栈、队列、树的实现方法示例...

    本文实例讲述了java数据结构之链表.栈.队列.树的实现方法.分享给大家供大家参考,具体如下: 最近无意中翻到一本书,闲来无事写几行代码,实现几种常用的数据结构,以备后查. 一.线性表(链表) 1.节 ...

  2. java有链表吗_Java数据结构之链表(Linked List)

    1.链表(Linked List)介绍 链表是有序的列表,但是它在内存存储结构如下: 2.特点: 链表是以节点的方式来存储,是链式存储 每个节点包含 data 域, next 域:指向下一个节点. 链 ...

  3. java链表的数据结构_Java数据结构 获取链表(LinkedList)的第一个和最后一个元素

    Java数据结构 获取链表(LinkedList)的第一个和最后一个元素 以下实例演示了如何使用 LinkedList 类的 linkedlistname.getFirst() 和 linkedlis ...

  4. java负零_java数据结构从零基础到负基础

    第一章 基础 1.3.32 栈与队列融合的数据结构:链表实现 1.接口public interface ISteque { /** * 进栈 * @param val 进栈元素 */ void pus ...

  5. java 获取叶子节点个数_数据结构编程: 统计二叉树中叶子结点的个数。

    展开全部 叶子节点:没有孩子节点的节点 也就是说,当我们明白了叶子节点的定义62616964757a686964616fe59b9ee7ad9431333363376531后,只需要遍历一遍二叉树,把 ...

  6. java单例设计模式懒汉_Java设计模式之单例设计模式(懒汉、饿汉)

    [toc] Java设计模式之单例设计模式(懒汉.饿汉) 相信面试过的初中级Java开发的朋友可能都有遇到过单例设计模式的笔试题吧,如果之前没有背下来或者不理解,可以看看下面这篇文章,应该足够应付笔试 ...

  7. python链表的创建_python数据结构之链表的实例讲解

    在程序中,经常需要将组(通常是同为某个类型的)数据元素作为整体 管理和使,需要创建这种元素组,变量记录它们,传进传出函数等. 组数据中包含的元素个数可能发变化(可以增加或删除元素). 对于这种需求,最 ...

  8. python中什么是链表_python中的数据结构-链表

    一.什么是链表 链表是由一系列节点构成,每个节点由一个值域和指针域构成,值域中存储着用户数据,指针域中存储这指向下一个节点的指针.根据结构的不同,链表可以分为单向链表.单向循环链表.双向链表.双向循环 ...

  9. python 释放链表节点_四种常见链表的实现及时间复杂度分析(Python3版)

    四种常见的链表包括:单向链表,单向循环链表,双向链表,双向循环链表. 要实现的链表操作包括 - is_empty() 判断链表是否为空 - length() 求链表长度 - traversing() ...

最新文章

  1. 解决vim没有颜色的办法
  2. 【bzoj2770】YY的Treap 权值线段树
  3. python统计元素个数_python怎么统计列表中元素的个数
  4. DeepChem | DeepChem的图卷积特征化器
  5. 关于jQuery Mobile 的pageinit,pageshow,以及data-ajax
  6. 教程:Hibernate,JPA和Spring MVC –第2部分
  7. 404 单页应用 报错 路由_通过 Laravel 创建一个 Vue 单页面应用(五)
  8. Android 亮屏速度分析
  9. LeetCode 743. 网络延迟时间(最短路径)
  10. caffe,caffe2 and pytorch
  11. 【Elasticsearch】es 使用Rollup在Elasticsearch 6.3中合并旧日志 上卷 Rollup
  12. 二进制转8421bcd码_中山CVI转CVBS芯视音科技原装
  13. DeepDream网络
  14. 用gpg加密软件加密文件
  15. 灵活的IP网络测试工具——— X-Launch
  16. vue 点击按钮改变颜色
  17. Axure计算器原型
  18. linux 库全局变量_C语言开发单片机为什么大多数都采用全局变量的形式?
  19. R语言学习(六)——关联规则分析
  20. black Friday

热门文章

  1. QT示例:基于TCP点对点Socket通讯
  2. 一篇文章搞懂数据仓库:常用ETL工具、方法
  3. Jupyter 安装使用
  4. WEB三大攻击之—XSS攻击与防护
  5. Replace Array with Object(以对象取代数组)
  6. ActiveMQ消费者平滑关闭
  7. python hook_python_理解篇_钩子方法的理解
  8. python自动化工具哪个好用_微软最强 Python 自动化工具开源了!不用写一行代码!...
  9. storm的流分组策略
  10. rr计算机专业英语,《计算机专业英语》电子教本8.pdf