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

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

    代码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. Python爬虫系统化学习(2)

    Python爬虫系统学习(2) 动态网页爬取 当网页使用Javascript时候,很多内容不会出现在HTML源代码中,所以爬取静态页面的技术可能无法使用.因此我们需要用动态网页抓取的两种技术:通过浏览 ...

  2. Oracle数据库配置监听程序

    最近在学习Oracle数据库,从安装到配置监听程序基本靠百度... 不得不说百度真的很nice!!! 下面是我的Oracle服务端(PL/SQL Developer)出现的监听程序的问题及我解决的方法 ...

  3. 资源授权?对OAuth2.0的一次重新认识的过程

    什么是OAuth? OAuth一个开放的授权标准,允许用户在不提供关键信息(如账号,密码)给第三方应用的前提下,让第三方应用去访问用户在某网站上的资源(如头像,用户昵称等). OAuth分为OAuth ...

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

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

  5. 剑指 Offer 34. 二叉树中和为某一值的路径 + 记录所有路径

    剑指 Offer 34. 二叉树中和为某一值的路径 Offer_34 题目详情 题解分析 本题是二叉树相关的题目,但是又和路径记录相关. 在记录路径时,可以使用一个栈来存储一条符合的路径,在回溯时将进 ...

  6. Kafka SASL ACL配置踩坑总结

    源起:工程现阶段中间件采用的是kafka.满足了大数据的高吞吐,项目间的解耦合,也增强了工程的容错率与扩展性.但是在安全这一块还有漏洞,kafka集群中,只要网站内的任何人知道kafka集群的ip与t ...

  7. 大数据实战-Spark实战技巧

    1.连接mysql --driver-class-path mysql-connector-java-5.1.21.jar 在数据库中,SET GLOBAL binlog_format=mixed; ...

  8. Linux下找出吃内存的方法总结

    Linux下查询进程占用的内存方法总结,假设现在有一个「php-cgi」的进程 ,进程id为「25282」. 现在想要查询该进程占用的内存大小.linux命令行下有很多的工具进行查看,现总结常见的几种 ...

  9. [源码分析] 消息队列 Kombu 之 Consumer

    [源码分析] 消息队列 Kombu 之 Consumer 目录 [源码分析] 消息队列 Kombu 之 Consumer 0x00 摘要 0x01 综述功能 0x02 示例代码 0x03 定义 3.1 ...

  10. Android的Proxy/Delegate Application框架

    转自:http://blogs.360.cn/360mobile/2013/11/25/proxydelegate-application/#comment-77 有的时候,为了实现一些特殊需求,如界 ...