数据结构(2):单链表学习使用java实现
单链表是单向链表,它指向一个位置:
单链表常用使用场景:根据序号排序,然后存储起来。
代码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实现的更多相关文章
- 数据结构之单链表的实现-java
一.单链表基本概念 单链表是一种链式存取的数据结构,用一组地址任意的存储单元(一般是非连续存储单元)存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点的构成:元素data + 指针next ...
- 数据结构(一) 单链表的实现-JAVA
数据结构还是很重要的,就算不是那种很牛逼的,但起码得知道基础的东西,这一系列就算是复习一下以前学过的数据结构和填补自己在这一块的知识的空缺.加油.珍惜校园中自由学习的时光.按照链表.栈.队列.排序.数 ...
- 数据结构之单链表(基于Java实现)
链表:在计算机中用一组任意的存储单元存储线性表的数据元素称为链式存储结构,这组存储结构可以是连续的,也可以是不连续的,因此在存储数据元素时可以动态分配内存. 注:在java中没有指针的概念,可以理解为 ...
- Python数据结构之单链表
Python数据结构之单链表 单链表有后继结点,无前继结点. 以下实现: 创建单链表 打印单链表 获取单链表的长度 判断单链表是否为空 在单链表后插入数据 获取单链表指定位置的数据 获取单链表指定元素 ...
- 理解单链表的反转(java实现)
要求很简单,输入一个链表,反转链表后,输出新链表的表头. 反转链表是有2种方法(递归法,遍历法)实现的,面试官最爱考察的算法无非是斐波那契数列和单链表反转,递归方法实现链表反转比较优雅,但是对于不 ...
- javascript数据结构之单链表
下面是用javascript实现的单链表,但是在输出的时候insert方法中存在问题,chrome的console报错说不能读取空的属性,调试了很久都没有通过,先在这里存着,以后再来修改一下. //数 ...
- Java数据结构之单链表
这篇文章主要讲解了通过java实现单链表的操作,一般我们开始学习链表的时候,都是使用C语言,C语言中我们可以通过结构体来定义节点,但是在Java中,我们没有结构体,我们使用的是通过类来定义我们所需要的 ...
- Java数据结构-03单链表(二)
在之前我们封装了一些操作在接口类中,并在抽象类实现了相同的方法.下面我们开始写代码: 无头结点单链表:(注意下面的AbstractList是之前抽取的类,不是java.util包下的类) public ...
- 图解Java数据结构之单链表
本篇文章介绍数据结构中的单链表. 链表(Linked List)介绍 链表可分为三类: 单链表 双向链表 循环列表 下面具体分析三个链表的应用. 单链表 链表是有序的列表,它在内存中存储方式如下: 虽 ...
随机推荐
- Jump Server在docker中安装部署
安装部署: 1.准备机器: 官方环境要求: 硬件配置: 2个CPU核心, 4G 内存, 50G 硬盘(最低) 操作系统: Linux 发行版 x86_64 Python = 3.6.x Mysql S ...
- Spring IoC总结
Spring 复习 1.Spring IoC 1.1 基本概念 1.1.1 DIP(Dependency Inversion Principle) 字面意思依赖反转原则,即调用某个类的构造器创建对象时 ...
- Kubernetes 实战 —— 01. Kubernetes 介绍
简介 P2 Kubernetes 能自动调度.配置.监管和故障处理,使开发者可以自主部署应用,并且控制部署的频率,完全脱离运维团队的帮助. Kubernetes 同时能让运维团队监控整个系统,并且在硬 ...
- Flask:基本结构
在大多数标准中,Flask 都算是小型框架,小到可以称为"微框架".但是,小并不意味着它比其他框架的功能少.Flask 自开发伊始就被设计为可扩展的框架,它具有一个包含基本服务的强 ...
- 【粉丝问答10】C语言关键字static的使用详解
视频地址:https://www.ixigua.com/6935761378816819748 粉丝提问 粉丝问题,总结一下: 关键字static的使用方法. 要想搞清楚关键字static的使用方法, ...
- RocketMQ安装配置过程
官网 官方网站:http://rocketmq.apache.org 下载源码包:https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.8.0/r ...
- frameset、frame和div 、iframe
框架一般应用于首页的界面排版工作.把一个网页切割成多个页面管理.frame文件一般只包含框架的布局信息,不会包含其他内容,所有的页面效果都是在各个frameset页面内显示.他们都从属于frame文件 ...
- 字符串匹配-BF算法和KMP算法
声明:图片及内容基于https://www.bilibili.com/video/av95949609 BF算法 原理分析 Brute Force 暴力算法 用来在主串中查找模式串是否存以及出现位置 ...
- [HDU5592] ZYB's Premutation
[HDU5592] ZYB's Premutation 题目大意:一个由\([1,n]\)组成的数列,但不知道具体排列,但给出每个前缀的逆序对数目,让你还原排列 Solution 创造一颗\([1,n ...
- MongoDB学习--环境搭建记录
Mongo安装教程,参考英文官网 基本命令, 索引的引用,索引基于地理位置的数据, win10 64位 系统中安装虚拟机 win10 系统中安装虚拟机VMwareWorkstation11 并安装 L ...