一 . 链表的概述

1.1 链式存储:

用一组任意类型的存储单元存储线性表,在逻辑上面相邻的结点在物理位置上面不一定相邻。

1.2 链表:

采用链式存储方法的线性表叫做链表

1.3 链表的特点:

其结点的存储单元可以不连续,每个结点中除存储原表结点中的数据外,还须存储指示其直接后继或前趋结点的地址,以反映结点之间的逻辑关系。因此,链表中每个结点由两部分构成:数据域和链域。

链表没有固定的长度,可以在后面一直加

1.4 链表的分类

从实现角度可分为:动态链表和静态链表

从链接方式可分为:单链表、双链表和循环链表

二 . 单链表

指的是单向链表,每个节点的结构如下:

把结点的实现,用面向对象的方法分析,把结点归为一个Structural类。

Structural类中把数据域和后继节点都转为类的属性。

通常,我们定义一个链表,在他的第一个元素都不存储东西,让他只作为一个head标记,具体原因为什么?

因为链表有删除操作,如果要删除的是第一个结点,我们没有最前面head结点的话,就没有办法进行。

比如,数据域我们就存储一个name。

那么Node类的结构如下:

public class Structural {

public String name;

public Structural next;

}

我们可以把创建节点,分配空间的过程,在构造方法中完成

// 创建节点,分配空间public Structural(String name, Structural next) {

// TODO Auto-generated constructor stubthis.name = name;

this.next = next;

}

这样我们利用类的构造方法就可以完成,结点的创建过程。

因为链表最小单元,就是一个结点,我们就把链表的操作归给,这个结点的方法,写出静态方法,调用的时候,只需要直接用类名调用就行。

一个结点就是一个链表,如需加入更多结点只需要在后面接着加就好了!!!

下来开始写链表的操作:

(1)插入操作

// 插入操作(链表头节点,一个指定节点,要插入的节点) 插到指定节点之后public static void insert(Structural head, Structural index, Structural data) {

boolean flag = false;

// 如果头指针不存在,链表不存在if (head == null) {

return;

}

// 如果插入到头节点之后,也就是要成为第一个元素if (head.next == index) {

data.next = head.next;

head.next = data;

flag = true;

}

while (head.next != null) {

head = head.next;

if (head == index) {

data.next = head.next;

head.next = data;

flag = true;

break;

}

}

if (flag == true) {

System.out.println("插入成功");

} else {

System.out.println("插入失败");

}

}

(2)删除操作

代码实现:

// 删除操作(头节点,要删除节点)public static void dir(Structural head, Structural data) {

boolean flag = false;

// 如果头指针不存在,链表不存在if (head == null) {

System.out.println("删除失败");

return;

}

// 如果删除头节点if (head == data) {

head = head.next;

flag = true;

}

while (head.next != null) {

if (head.next == data) {

head.next = head.next.next;

flag = true;

break;

}

head = head.next;

}

if (flag) {

System.out.println("删除成功");

} else {

System.out.println("删除失败");

}

}

(3) 修改操作

代码实现:

public static void revise(Structural head, Structural str1, Structural str2) {

boolean flag = false;

if (head == null) {

System.out.println("修改失败");

}

while (head.next != null) {

if (head.next == str1) {

str2.next = head.next.next;

head.next = str2;

flag = true;

break;

}

head = head.next;

}

if (flag) {

System.out.println("修改成功");

} else {

System.out.println("修改失败");

}

}

测试:

public class LinkedList {

public static void main(String[] args) {

Structural head = new Structural(null, null);

Structural structural1 = new Structural("a",null);

Structural structural2 = new Structural("b",null);

Structural structural3 = new Structural("c",null);

Structural structural4 = new Structural("d",null);

Structural structural5 = new Structural("e",null);

//单向链表head.next = structural1;

structural1.next = structural2;

structural2.next = structural3;

structural3.next = structural4;

structural4.next = structural5;

for(Structural structural = head ; structural != null ;structural = structural.next) {

System.out.println(structural);

}

System.out.println("---------------------");

//插入(把f插到d后面)Structural structural6 = new Structural("f", null);

Structural.insert(head, structural4, structural6);

for(Structural structural = head ; structural != null ;structural = structural.next) {

System.out.println(structural);

}

System.out.println("---------------------");

//删除(把f删除)中间元素删除Structural.dir(head, structural6);

for(Structural structural = head ; structural != null ;structural = structural.next) {

System.out.println(structural);

}

System.out.println("---------------------");

//删除(把a删除)头节点删除Structural.dir(head, structural1);

for(Structural structural = head ; structural != null ;structural = structural.next) {

System.out.println(structural);

}

System.out.println("---------------------");

//删除(把e删除)末尾节点删除Structural.dir(head, structural5);

for(Structural structural = head ; structural != null ;structural = structural.next) {

System.out.println(structural);

}

System.out.println("---------------------");

//修改(把c改为g)Structural structural7 = new Structural("g", null);

Structural.revise(head,structural3, structural7);

for(Structural structural = head ; structural != null ;structural = structural.next) {

System.out.println(structural);

}

System.out.println("---------------------");

}

}

结果:+

Structural [name=null]

Structural [name=a]

Structural [name=b]

Structural [name=c]

Structural [name=d]

Structural [name=e]

---------------------

插入成功

Structural [name=null]

Structural [name=a]

Structural [name=b]

Structural [name=c]

Structural [name=d]

Structural [name=f]

Structural [name=e]

---------------------

删除成功

Structural [name=null]

Structural [name=a]

Structural [name=b]

Structural [name=c]

Structural [name=d]

Structural [name=e]

---------------------

删除成功

Structural [name=null]

Structural [name=b]

Structural [name=c]

Structural [name=d]

Structural [name=e]

---------------------

删除成功

Structural [name=null]

Structural [name=b]

Structural [name=c]

Structural [name=d]

---------------------

修改成功

Structural [name=null]

Structural [name=b]

Structural [name=g]

Structural [name=d]

---------------------

终于无聊的把自己的思路说完了。

三 . 一道经典的算法题——判断单链表是否有环

先看看链表可能出现的情况,所有单链表无非三种情况

* 第一种:从头节点指向下个,一直指下去,最后一个结点的next指向null

* 第二种:从头节点指向下个,一直指下去,最后一个结点的next指向头节点,形成一个首尾相连的环链表

* 第三种:从头节点指向下个,一直指下去,最后一个结点的next指向局部节点,形成一个局部尾部有环的链表。

关于如何判断单链表是否有环,有三种解法:

(1)先定义1个结点,先让他等于头节点,然后向后遍历,遍历一次,和头节点对比一次,如果出现相同,说明链表有环,如果没有出现相等情况,则说明没有环。

但是这种算法只能处理,前两种情况,因此缺乏普遍性,不适用。

(2)遍历链表,每遍历一个,把他们的hashcode值,先和数组里面的比较,如果没有再存储到一个数组里,如果找到有重复的,就说明有环。

(3)算法效率最高的,定义两个指针,一个跑得快,一个跑得慢,有一天他两相遇了,说明有环

例子:两个人都沿着跑步,都向前跑,一个跑的快,一个跑得慢,有一天他两相遇了,说明跑道中有环。

代码实现:

public static boolean hasLoop(Structural head) {

if(head == null) {

return false;

}

//定义一个跑的快的,每次遍历两个节点Structural stru1 = head;

//定义一个跑的慢的,每次遍历一个节点Structural stru2 = head;

while(true) {

//避免一开始就相遇,让跑的快的,先跑两步。stru1 = stru1.next.next;

stru2 =stru2.next;

if(stru1 == null) {

System.out.println("链表没有环");

return false;

}

if(stru2 == stru1) {

System.out.println("链表有环");

return true;

}

}

}

数据结构 java c_数据结构——链表(用Java实现C语言的指针,思想)相关推荐

  1. 数据结构1:单链表反转java代码解释

    来源于尚硅谷的老师代码,只因其中有几行代码自己课上没听明白,课后自己整理了一下 首先完整代码如下: //将单链表反转 public static void reversetList(HeroNode ...

  2. php java c_当PHP、Java、C、C++ 这几种编程语言变成汽车是什么样的场景?

    在学习和工作中,人们常常会把各种编程语言拿出来做对比,特别是刚刚开始入门学习IT的同学.实际上,每门语言自己的优缺点有时候也正是语言本身的特性,在学习中,我们更应该关心的是应用场景,哪门语言适合哪个场 ...

  3. 【数据结构】循环单链表的实现(C语言)

    循环单链表应掌握以下基本操作: 1.建立一个空的循环单链表. 2.获得循环单链表的最后一个结点的位置. 3.输出循环单链表中各结点的值. 4.在循环单链表中查找值为x的结点. 5.在循环单链表中第i个 ...

  4. 单链表插入元素 注释 c语言,数据结构之无头单链表的相关练习题——C语言实现(详细注释)...

    本文中所用到的相关链表操作实现均在我上篇博客中:https://blog..net/haoziai905/article/details/87099287 1.删除无头单链表的非尾结点 这道题的重点就 ...

  5. Java实现单链表、栈、队列三种数据结构

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:远航 cnblogs.com/yang-guang- ...

  6. java双链表基本方法_Java数据结构之双端链表原理与实现方法

    本文实例讲述了Java数据结构之双端链表原理与实现方法.分享给大家供大家参考,具体如下: 一.概述: 1.什么时双端链表: 链表中保持这对最后一个连点引用的链表 2.从头部插入 要对链表进行判断,如果 ...

  7. java数据接口之链表_Java数据结构和算法之链表

    三.链表 链结点 在链表中,每个数据项都被包含在'点"中,一个点是某个类的对象,这个类可认叫做LINK.因为一个链表中有许多类似的链结点,所以有必要用一个不同于链表的类来表达链结点.每个LI ...

  8. java环形链表_数据结构和算法(四)Java实现环形链表

    1. 数据结构和算法(四)Java实现环形链表 1.1 约瑟夫问题 约瑟夫问题:公元66年,约瑟夫不情愿地参与领导了犹太同胞反抗罗马统治的起义,后来起义失败,他和一些宁死不降的起义者被困于一个山洞之中 ...

  9. 用Java描述数据结构之线性表的链式存储(链表),模拟LinkedList实现

    上一篇介绍了顺序表:用Java描述数据结构之线性表的顺序存储(顺序表),ArrayList及其方法的介绍 上一篇博客中说明了什么是线性表--线性表就是一个个数据元素逻辑上以一对一的相邻关系(但是在物理 ...

最新文章

  1. 加速SaaS规模化演进,餐道基于K8s的云上创新底座
  2. no suitable driver found for jdbc:mysql//localhost:3306/..
  3. 谈谈疑似中介规则策略
  4. Node.js 与 JavaScript 基金会正式合并,JS 喜提新主场
  5. VC++:如何将程序最小化到托盘 [转]
  6. DirectX9 3D 快速上手 1
  7. php laravel 相关收集
  8. vulhub靶场sql注入漏洞复现
  9. 数学之美系列好文,强推
  10. 用观察者模式设计一个气象台
  11. 从古至今的计算机设备,计算器从古至今的发展形成
  12. matlab qua2d,matlab 几个关于GPS/INS和GPS/AHRS的程序 - 下载 - 搜珍网
  13. 【它山之石,可以攻玉】关于求职(实习)面试经验(2)
  14. 文献调研之如何查找文献及源码
  15. DM error code 达梦数据库-错误代码 汇总
  16. 独家:被纽约时报、华尔街日报报道的Senior Living是如何成为美国养老产业的“流量IP”?
  17. Flutter:加载本地Html、WebView与JS交互
  18. firefox 14 vim化——Pentadactyl
  19. Cadence中原理图模块化
  20. 轻量级网络——ShuffleNetV1

热门文章

  1. 【图像处理】图像拼接原理介绍
  2. appium向右滑动
  3. JS继承六种方式详解
  4. 机器学习之---马尔可夫随机场实例
  5. Linux安装maven(详细教程)
  6. idea万能快捷键(alt enter),你不知道的17个实用技巧!!!
  7. Watcher--数据变更的通知
  8. Arduino基础学习-声音信号输出
  9. 前端特效CSS样式樱花
  10. C-Lodop提示“有窗口已打开,先关闭它(持续如此请刷新页面)!”