单链表是单向链表,它指向一个位置:

    单链表常用使用场景:根据序号排序,然后存储起来。

    代码Demo:

    

package com.Exercise.DataStructure_Algorithm.SingleList;

import java.util.Stack;

public class SingleTest1 {
public static void main(String[] args) {
Node node1 = new Node(1, "admin1");
Node node2 = new Node(2, "admin2");
// Node node3 =new Node(3,"admin2");
Node_Manage node_manage = new Node_Manage();
// node_manage.list(); node_manage.add3(node1);
node_manage.add3(node2);
// node_manage.add3(node3);
System.out.println("显示数据:");
// node_manage.add3(node3);
node_manage.list();
// Node node4 =new Node(2,"admin3");
// Node node5 =new Node(4,"admin4");
// node_manage.update(node4);
// node_manage.update(node5);
// //修改后显示数据
// System.out.println();
// System.out.println("修改后的数据:");
// node_manage.list();
// System.out.println("删除后的数据显示:");
// //node_manage.delete(0);
// node_manage.list();
// int length = SingleTest1.getLength(node_manage.getHeader());
// //int length1 = SingleTest1.getLength(node_manage.getSignx());
// System.out.println("单链表长度是:"+length);
// System.out.println("倒数第一个节点数据内容:");
// //查找倒数第1个节点的数据
// Node node = SingleTest1.findNode(node_manage.getHeader(), 1);
// System.out.println(node);
// System.out.println("正向第一个数据节点数据内容:");
// //查找正向第一个节点数据
// Node nodeT = SingleTest1.find2Node(node_manage.getHeader(),3);
// System.out.println(nodeT);
System.out.println("翻转后数据内容:");
//翻转
// SingleTest1.reversalList(node_manage.getHeader());
// SingleTest1.reversalList(node_manage.getHeader());
SingleTest1.reverse2(node_manage.getHeader());
// node_manage.list();
} //求节点有效个数 从头节点开始 节点长度
public static int getLength(Node header) {
//如果节点为空,说明长度为0
if (header.next == null) {
return 0;
}
//辅助节点,从头节点的下一个节点开始
Node current = header.next;
int length = 0;
while (current != null) {
//如果节点没走到尾
length++;
current = current.next;
}
return length;
} //查找倒数第n个节点的数据
public static Node findNode(Node node, int index) {
if (node.next == null) {
System.out.println("单链表没有数据,无法进行节点查找");
}
Node current = node.next;
//获取长度
int size = getLength(node);
System.out.println(size);
if (index <= 0 || index > size) {
return null;
}
for (int i = 0; i < size - index; i++) {
current = current.next;
}
return current;
} //查找正向第n个节点的数据
public static Node find2Node(Node node, int index) {
if (node.next == null) {
System.out.println("单链表没有数据,无法进行节点查找");
}
Node current = node;
//获取长度
int size = getLength(node);
System.out.println(size);
if (index <= 0 || index > size) {
return null;
}
for (int i = 0; i < index; i++) {
current = current.next;
}
return current;
} //[] [1] [2] [3] old
//[] [3] [2] [1]
//new: [3] [2] [1]
//old.next = new.next
//old = [3] [2] [1]
//翻转
public static void reversalList(Node node) {
Node current = node.next;
Node next = null;
//初始化
Node reverseNode = new Node(0, "");
while (current != null) {
next = current.next;
current.next = reverseNode.next;
reverseNode.next = current;
current = next;
}
node.next = reverseNode.next;
} public static void reverse(Node head) {
//存储数据的
Node current = head.next;
//初始化 新的翻转节点
Node reverseNode = new Node(0,"");
Node next = null;
//如果不为空就翻转
while(current!=null){
//存储数据的下一个节点
next = current.next;
current.next = reverseNode.next;
//摘取current的数据内容给新的翻转节点
reverseNode.next = current;
//把current指向下一个节点
current = next;
}
head.next = current.next;
} //单链表反转使用堆栈 先进后出的原理逆序实现
public static void reverse2(Node head){
Node current = head.next;
Stack<Node> nodes = new Stack<Node>();
if(head.next == null){
System.out.println("单链表为空");
}
while(current!=null){
nodes.push(current);
current = current.next;
} while(nodes.size()>0){
Node pop = nodes.pop();
System.out.println(pop);
}
} } class Node_Manage{
//单链表初始化
Node signx =new Node(0,""); public Node getSignx() {
return signx;
} Node header = signx; public Node getHeader() {
return header;
} Node tail = header;
// header tail
// [] ---> [] ---> [] ---> [] ----> [] ---> []
//链表创建插入数据
//没有顺序的添加插入数据
public void add(Node new_node){
Node current = header;
while(true){
if(current.next==null){
break;
}
current = current.next; }
current.next = new_node;
} //没有顺序的添加插入数据
// t t --> t
// [] ---> [1]--->[2] --[3]
public void add2(Node new_node){
tail.next = new_node;
tail = tail.next;
} //按顺序插入数据
// 1 2 3
// [] --> [*] --> []
public void add3(Node new_node){
Node current = header;
//标识符
boolean flag = false;
while(true){
if(current.next==null){
break;
}else if(current.next.id > new_node.id){
break;
}else if(current.next.id == new_node.id){
flag = true;
break;
}
current = current.next;
} if(flag){
System.out.println("链表里面已经有这个节点了,无法添加数据了");
}else{
// (代加入的数据*)
// [*]
//[] -- -- []
//新增数据
new_node.next = current.next;
current.next = new_node;
}
} //删除单链表节点
public void delete(int node){
if(header == null){
System.out.println("要删除的节点的单链表为空");
}
Node current = header;
boolean flag = false;
while(true){
//链表走到了最后
if(current.next==null){
break;
}
//如果找到了,标识符就为true
if(current.next.id == node){
flag = true;
break;
}
//向后移动
current = current.next;
}
/*如果找到了
current -> next -> next
//[1] [待删除的2] [3]*/
//[1] [3]
if(flag){
current.next = current.next.next;
}else{
System.out.println("这个节点不在单链表中,无法删除");
}
} //单链表修改 根据id进行修改
public void update(Node NewNode){
if(header.next==null){
System.out.println("当前单链表为空");
}
Node current = header.next;
boolean flag = false; //标识符 默认是false
while(true){
if(current==null){
break;
}
if(current.id == NewNode.id){
flag = true;
break;
}
current = current.next;
}
if(flag){
current.name = NewNode.name;
}else{
System.out.printf("单链表中不存在%d数字的节点,无法修改",NewNode.id);
} } //显示链表
public void list(){
Node current = header.next;
while(true){
System.out.println(current);
if(current == null){
break;
}
if(current.next==null){
break;
}
current = current.next;
}
} } class Node{
public int id;
public String name;
public Node next;
public Node(int id,String name){
this.id=id;
this.name=name;
} @Override
public String toString() {
return "Signx{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}

  其中最想说的就是关于单链表的翻转这一块的理解,简单的画了个图,非使用堆栈的逆序方法:

    

这块翻转的代码:

  

 //[] [1] [2] [3] old
//[] [3] [2] [1]
//new: [3] [2] [1]
//old.next = new.next
//old = [3] [2] [1]
//翻转
public static void reversalList(Node node) {
Node current = node.next;
Node next = null;
//初始化
Node reverseNode = new Node(0, "");
while (current != null) {
next = current.next;
current.next = reverseNode.next;
reverseNode.next = current;
current = next;
}
node.next = reverseNode.next;
}

  参考:韩顺片java数据结构和算法  

数据结构(2):单链表学习使用java实现的更多相关文章

  1. 数据结构之单链表的实现-java

    一.单链表基本概念 单链表是一种链式存取的数据结构,用一组地址任意的存储单元(一般是非连续存储单元)存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点的构成:元素data + 指针next ...

  2. 数据结构(一) 单链表的实现-JAVA

    数据结构还是很重要的,就算不是那种很牛逼的,但起码得知道基础的东西,这一系列就算是复习一下以前学过的数据结构和填补自己在这一块的知识的空缺.加油.珍惜校园中自由学习的时光.按照链表.栈.队列.排序.数 ...

  3. 数据结构之单链表(基于Java实现)

    链表:在计算机中用一组任意的存储单元存储线性表的数据元素称为链式存储结构,这组存储结构可以是连续的,也可以是不连续的,因此在存储数据元素时可以动态分配内存. 注:在java中没有指针的概念,可以理解为 ...

  4. Python数据结构之单链表

    Python数据结构之单链表 单链表有后继结点,无前继结点. 以下实现: 创建单链表 打印单链表 获取单链表的长度 判断单链表是否为空 在单链表后插入数据 获取单链表指定位置的数据 获取单链表指定元素 ...

  5. 理解单链表的反转(java实现)

    要求很简单,输入一个链表,反转链表后,输出新链表的表头.   反转链表是有2种方法(递归法,遍历法)实现的,面试官最爱考察的算法无非是斐波那契数列和单链表反转,递归方法实现链表反转比较优雅,但是对于不 ...

  6. javascript数据结构之单链表

    下面是用javascript实现的单链表,但是在输出的时候insert方法中存在问题,chrome的console报错说不能读取空的属性,调试了很久都没有通过,先在这里存着,以后再来修改一下. //数 ...

  7. Java数据结构之单链表

    这篇文章主要讲解了通过java实现单链表的操作,一般我们开始学习链表的时候,都是使用C语言,C语言中我们可以通过结构体来定义节点,但是在Java中,我们没有结构体,我们使用的是通过类来定义我们所需要的 ...

  8. Java数据结构-03单链表(二)

    在之前我们封装了一些操作在接口类中,并在抽象类实现了相同的方法.下面我们开始写代码: 无头结点单链表:(注意下面的AbstractList是之前抽取的类,不是java.util包下的类) public ...

  9. 图解Java数据结构之单链表

    本篇文章介绍数据结构中的单链表. 链表(Linked List)介绍 链表可分为三类: 单链表 双向链表 循环列表 下面具体分析三个链表的应用. 单链表 链表是有序的列表,它在内存中存储方式如下: 虽 ...

随机推荐

  1. 【JAVA并发第四篇】线程安全

    1.线程安全 多个线程对同一个共享变量进行读写操作时可能产生不可预见的结果,这就是线程安全问题. 线程安全的核心点就是共享变量,只有在共享变量的情况下才会有线程安全问题.这里说的共享变量,是指多个线程 ...

  2. oracle 19c 导入 12c ORA-39002 ORA-39358

    直接用19c导出的dmp文件导入到12c,报错: ORA-39002: invalid operation ORA-39358: Export dump file version 19.0.0.0.0 ...

  3. 2021-2-27:Linux 下如何优化 Java MMAP 写入

    主要是调整 pdflush 相关参数. 在linux操作系统中,写操作是异步的,即写操作返回的时候数据并没有真正写到磁盘上,而是先写到了系统cache里,随后由pdflush内核线程将系统中的脏页写到 ...

  4. 由剑指offer引发的思考——对象中虚函数指针的大小

    先看一个简单的问题: 一.定义一个空的类型,对于其对象我们sizeof其大小,是1字节.因为我们定义一个类型,编译器必须为其分配空间,具体分配多少是编译器决定,vs是1字节,分配在栈区. 那,这一个字 ...

  5. APP跳转小程序,小程序跳转APP

    关注公共号,搜索 "APP跳转小程序,小程序跳转APP",查看原文 前置条件: 开发环境:windows 开发框架:uni-app , H5+,nativeJS,mpvue 编辑器 ...

  6. HDOJ-1711(KMP算法)

    Number Sequence HDOJ-1711 1.这里使用的算法是KMP算法,pi数组就是前缀数组. 2.代码中使用到了一个技巧就是用c数组看成是复合字符串,里面加一个特殊整数位-1000006 ...

  7. Linux速通07 硬盘分区、格式化及文件系统管理

    硬件设备与文件名的对应关系 # 在Linux系统中,每个设备都被当作一个文件来对待 # 各种设备在Linux中的文件名 设备 设备在Linux内的文件名 IDE硬盘 /dev/hd[a-d] SCSI ...

  8. fastjson<=1.2.47反序列化漏洞复现

    0x00:前言 这个漏洞爆出来之后本来一直打算挑时间去复现,后来一个朋友突然发来他们站点存在fastjson这个漏洞被白帽子发了报告.既然漏洞环境送上门来,我便打算直接下手试一试.在我的想象中当然是一 ...

  9. JAVA -JSON-XML-MAP转换

      //定义一个MAP对象,将对象传给后端接口接收 Map a = ["api": '11', ZGUID: "1231",BESKZ: "1231& ...

  10. 优秀的vue服务端渲染框架

    目前国内优秀的基于vue的ssr框架有minissr,可以在服务端生成html代码,有利于搜索引擎爬取. https://www.wechatmini.com/vue/minissr 使用方法可以参考 ...