链表(图解)及简单实现(Java)
一、链表的概念
链表是是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
链表分为单链表、双链表、循环链表
二、链表的实现(以单链表为例)
1.单链表
1.)什么是单链表:
单向链表是一种线性表,实际上是由节点(Node)组成的,一个链表拥有不定数量的节点。其数据在内存中存储是不连续的,它存储的数据分散在内存中,每个节点只能也只有它能知道下一个节点的存储位置。由N各节点(Node)组成单向链表,每一个Node记录本Node的数据及下一个Node。向外暴露的只有一个头结点(Head),我们对链表的所有操作,都是直接或者间接地通过其头结点来进行的。
2.)单链表的图解
2.单链表的代码实现
1).单链表及结点的定义
class SingleList{Node head;//定义一个头节点,头节点不动,不存放具体的值private int Length;//链表的长度public SingleList(){head=null;Length = 0 ;}//返回链表的长度public int length(){return this.Length;}//判断所需要操作位置的节点是否存在private void outLength(int index){if(this.Length < index || index < 0 ){ //需要操作位置大于链表长度,则抛出错误throw new IndexOutOfBoundsException();}}}//定义一个Node,每个Node就是一个节点
class Node {private int data;public Node next;public Node(int data) {this.data = data;}@Overridepublic String toString() {return "Node{" +" data='" + data + '\'' +'}';}
}
2).链表的增删改查实现
增加节点:a.增加头节点 ;b.在指定索引处增加节点;c.在链表尾部增加节点
/**添加节点到单链表头节点* @param node*/public void addHead(Node node){//因为Head 为 null 所有直接将 head 给 node 的指向就行node.next = this.head;this.head = node;this.Length++;}/**加入结点到指定位置* 1.首先判断索引是否越界,越界则抛出异常* 2.循环,到指定索引 前一个索引 所在 结点 停止* 1.)将停止所在当前 结点 指向的 下一个结点 指向 Node 的下一个的结点* 2.)再将当前所在的 结点 指向Node* @param index* @param node*/public void add(int index ,Node node ){outLength(index);//需要操作位置大于链表长度,则抛出错误if(index == 0 ){ //若要添加位置再头节点,直接调用add(方法)addHead(node);return;}Node temp = head; // 辅助链表while (index >1 ){temp = temp.next; //指向下一个节点index --;}node.next = temp.next;//当前 节点 指向的 下一个节点 指向 Node 的下一个的节点temp.next = node ;this.Length++; //链表长度加1}/**添加节点到单链表末尾* @param node*/public void addList(Node node){add(Length,node ); //index 为链表的长度}
删除节点:a.删除头节点;b.删除指定索引位置的节点;c.删除尾部节点
/** 删除头节点* 并返回所删除的结点,链表长度减 1* @return*/public Node removeHead(){//判断链表是否为空if(Length == 0){return null ;}//定义一个Node 接收原先的头节点Node node = head ;head = head.next ; //然后删掉原头节点node.next =null; //将原先头节点的指向改成 nullthis.Length--;return node;}/**删除指定位置的元素* 并返回所删除的节点,链表长度减 1* @param index* @return*/public Node remove(int index){outLength(index-1);//需要操作位置大于链表长度,则抛出错误boolean flag = true;Node temp = head; // 辅助链表Node node = null;while (flag){if(index-1 < 1 ){flag = false ;break;}temp = temp.next; //指向下一个节点index --;}node = temp.next; //储存要删除的节点,便于返回temp.next = temp.next.next;node.next = null;this.Length--; //链表长度减1return node;}/**删除链表尾部节点* 并返回所删除的节点,链表长度减 1* 调用remover*/public Node removeList(){Node node = remove(this.Length-1);this.Length--;return node;}
查询指定节点
/**查询指定节点** @param index* @return*/public Node showNode(int index){outLength(index);boolean flag = true;Node temp = head; // 辅助链表//将指针指向指定节点while (flag){if(index < 1 ){flag = false ;break;}temp = temp.next; //指向下一个节点index --;}return temp;}/*** 遍历链表*/public void showList(){if(head == null){System.out.println("此链表为空");}Node temp = head ;while (temp != null){System.out.println(temp);temp=temp.next; //指向下一个节点}}
修改指定节点
/**修改指定结点信息* @param index* @return*/public Node upData(int index , Node upNode){outLength(index);boolean flag = true;Node temp = head; // 辅助链表Node node = null;//将指针指向指定节点的前一位while (index == 1 ){temp = temp.next; //指向下一个节点index --;}node = temp; // 用来储存修改前的节点upNode.next = temp.next.next; //将修改后节点 指向 修改前 下一个节点temp.next = upNode; //修改节点信息node.next = null; // 将前节点的指向改为 nullreturn node;}
}
3.)测试代码
public static void main(String[] args) {SingleList sl1 = new SingleList();Node n1 = new Node(1);Node n2 = new Node(2);Node n3 = new Node(3);Node n4 = new Node(4);Node n5 = new Node(5);//插入头节点sl1.addHead(n1);sl1.addHead(n2);//打印全部节点sl1.showList();System.out.println("--------");//插入头节点sl1.addHead(n3);//打印全部节点sl1.showList();System.out.println("--------");//插入链表尾部sl1.addList(n4);//打印全部节点sl1.showList();System.out.println("--------");//指定索引处加入节点sl1.add(2,n5);//打印全部节点sl1.showList();System.out.println("此时链表长度为:"+ sl1.length());System.out.println("--------");//删除头节点sl1.removeHead();//打印全部节点sl1.showList();System.out.println("--------");//删除尾部节点sl1.removeList();//打印全部节点sl1.showList();System.out.println("--------");//删除指定位置节点sl1.remove(1);//打印全部节点sl1.showList();System.out.println("此时链表长度为:"+ sl1.length());System.out.println("--------");//修改节点sl1.upData(0,new Node (8));//打印全部节点sl1.showList();System.out.println("此时链表长度为:"+ sl1.length());System.out.println("--------");//查询指定节点System.out.println(sl1.showNode(0));}
}
完整代码
public class SingleListDome {public static void main(String[] args) {SingleList sl1 = new SingleList();Node n1 = new Node(1);Node n2 = new Node(2);Node n3 = new Node(3);Node n4 = new Node(4);Node n5 = new Node(5);//插入头节点sl1.addHead(n1);sl1.addHead(n2);//打印全部节点sl1.showList();System.out.println("--------");//插入头节点sl1.addHead(n3);//打印全部节点sl1.showList();System.out.println("--------");//插入链表尾部sl1.addList(n4);//打印全部节点sl1.showList();System.out.println("--------");//指定索引处加入节点sl1.add(2,n5);//打印全部节点sl1.showList();System.out.println("此时链表长度为:"+ sl1.length());System.out.println("--------");//删除头节点sl1.removeHead();//打印全部节点sl1.showList();System.out.println("--------");//删除尾部节点sl1.removeList();//打印全部节点sl1.showList();System.out.println("--------");//删除指定位置节点sl1.remove(1);//打印全部节点sl1.showList();System.out.println("此时链表长度为:"+ sl1.length());System.out.println("--------");//修改节点sl1.upData(0,new Node (8));//打印全部节点sl1.showList();System.out.println("此时链表长度为:"+ sl1.length());System.out.println("--------");//查询指定节点System.out.println(sl1.showNode(0));}
}class SingleList{Node head;//定义一个头节点,头节点不动,不存放具体的值private int Length;//链表的长度public SingleList(){head=null;Length = 0 ;}/** 将链表反转** @param head* @return*/public static Node reverseIteratively(Node head){Node next = null;Node temp = head; // 辅助节点Node reverse = null;//用来储存逆转后的链表while(temp == null){}return null;}//返回链表的长度public int length(){return this.Length;}//判断所需要操作位置的节点是否存在private void outLength(int index){if(this.Length < index || index < 0 ){ //需要操作位置大于链表长度,则抛出错误throw new IndexOutOfBoundsException();}}/**添加节点到单链表头节点* @param node*/public void addHead(Node node){//因为Head 为 null 所有直接将 head 给 node 的指向就行node.next = this.head;this.head = node;this.Length++;}/**加入结点到指定位置* 1.首先判断索引是否越界,越界则抛出异常* 2.循环,到指定索引 前一个索引 所在 结点 停止* 1.)将停止所在当前 结点 指向的 下一个结点 指向 Node 的下一个的结点* 2.)再将当前所在的 结点 指向Node* @param index* @param node*/public void add(int index ,Node node ){outLength(index);//需要操作位置大于链表长度,则抛出错误if(index == 0 ){ //若要添加位置再头节点,直接调用add(方法)addHead(node);return;}Node temp = head; // 辅助链表while (index >1 ){temp = temp.next; //指向下一个节点index --;}node.next = temp.next;//当前 节点 指向的 下一个节点 指向 Node 的下一个的节点temp.next = node ;this.Length++; //链表长度加1}/**添加节点到单链表末尾* @param node*/public void addList(Node node){add(Length,node ); //index 为链表的长度}/** 删除头节点* 并返回所删除的结点,链表长度减 1* @return*/public Node removeHead(){//判断链表是否为空if(Length == 0){return null ;}//定义一个Node 接收原先的头节点Node node = head ;head = head.next ; //然后删掉原头节点node.next =null; //将原先头节点的指向改成 nullthis.Length--;return node;}/**删除指定位置的元素* 并返回所删除的节点,链表长度减 1* @param index* @return*/public Node remove(int index){outLength(index-1);//需要操作位置大于链表长度,则抛出错误boolean flag = true;Node temp = head; // 辅助链表Node node = null;while (flag){if(index-1 < 1 ){flag = false ;break;}temp = temp.next; //指向下一个节点index --;}node = temp.next; //储存要删除的节点,便于返回temp.next = temp.next.next;node.next = null;this.Length--; //链表长度减1return node;}/**删除链表尾部节点* 并返回所删除的节点,链表长度减 1* 调用remover*/public Node removeList(){Node node = remove(this.Length-1);this.Length--;return node;}/**查询指定节点** @param index* @return*/public Node showNode(int index){outLength(index);boolean flag = true;Node temp = head; // 辅助链表//将指针指向指定节点while (flag){if(index < 1 ){flag = false ;break;}temp = temp.next; //指向下一个节点index --;}return temp;}/*** 遍历链表*/public void showList(){if(head == null){System.out.println("此链表为空");}Node temp = head ;while (temp != null){System.out.println(temp);temp=temp.next; //指向下一个节点}}/**修改指定结点信息* @param index* @return*/public Node upData(int index , Node upNode){outLength(index);boolean flag = true;Node temp = head; // 辅助链表Node node = null;//将指针指向指定节点的前一位while (index == 1 ){temp = temp.next; //指向下一个节点index --;}node = temp; // 用来储存修改前的节点upNode.next = temp.next.next; //将修改后节点 指向 修改前 下一个节点temp.next = upNode; //修改节点信息node.next = null; // 将前节点的指向改为 nullreturn node;}
}//定义一个Node,每个Node就是一个节点
class Node {private int data;public Node next;public Node(int data) {this.data = data;}@Overridepublic String toString() {return "Node{" +" data='" + data + '\'' +'}';}
}
链表(图解)及简单实现(Java)相关推荐
- 数据结构java版txt,图解数据结构:使用Java
图解数据结构:使用Java 下载 mobi epub pdf ☆☆☆☆☆ 胡昭民 著 下载链接在页面底部 发表于2021-03-10 图书介绍 出版社: 清华大学出版社 ISBN:9787302402 ...
- 编写运行最简单的java程序——使用记事本编写java程序
编写运行最简单的java程序--使用记事本编写java程序 第一个java程序--使用记事本编辑 经过上篇文章的java环境搭建成功的小伙伴们可以在自己的计算机上编写属于自己的java程序了yo~ 还 ...
- 用java做一个简单记事本_用记事本写一个简单的java程序
用记事本写一个简单的java程序 第一步: 安装好jdk,并设置好环境变量. 桌面-计算机(右键)-属性-高级系统设置-环境变量-path-在变量值后加上:和jdk安装路径加上(路径即为C:\Prog ...
- Intellij Idea创建一个简单的java项目
2016年11月12日 我即将要离开象牙塔(校园),踏入社会,想想未来我是某个公司的一个程序员,再对比一下小时的梦想,好像出入挺大的.今天我不得不为即将的工作准备,一个java开发工程师,但是我现在是 ...
- 基于链表实现队列(基于Java实现)
title: 基于链表实现队列(基于Java实现) tags: 链表 队列 基于链表的队列实现方法的原理: 基于链表的实现,跟前面的基于数组实现一样,同样也需要两个指针:head指针和tail指针.它 ...
- 一个简单的Java web服务器实现
前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...
- java的同步关键字_简单了解Java synchronized关键字同步
简单了解Java synchronized关键字同步 发布于 2021-1-13| 复制链接 摘记: synchronized synchronized可以用来同步块,同步方法.同步块可以用来更精确 ...
- 一个简单的Java计时器项目,附源码
学Java开发的小伙伴都会想着做一些项目来检验自己的学习成果,今天小千就来分享一个简单的Java计时器项目,源码也放在文中,大家可以参考一下. Java计时器项目 开发环境:win8+eclipse+ ...
- java链表实现_数据结构——基于java的链表实现(真正理解链表这种数据结构)...
一.链表介绍 1.什么是链表? 链表是一种物理存储结构上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.如下图所示,在数据结构中,a1里面的指针存储着a2的地址,这样一个 ...
- 超简单的java爬虫
最简单的爬虫,不需要设定代理服务器,不需要设定cookie,不需要http连接池,使用httpget方法,只是为了获取html代码... 好吧,满足这个要求的爬虫应该是最基本的爬虫了.当然这也是做复杂 ...
最新文章
- 第一章:点云中的滤波问题---Filters
- linux线程函数大全
- Lucene打分规则与Similarity模块详解
- mybatis学习7之动态sql
- 面向过程的ado建造者模式
- 数据结构之最小生成树
- 编程语言分类 -- 强类型与弱类型、动态类型与静态类型
- 《Python预测之美》送书活动,拿走不谢~
- SharePoint 网站搬迁
- 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第4节 方法引用_2_方法引用_通过对象名引用成员方法...
- centos 7 安装韩文字体
- 密码学常见基本概念-随机数,伪随机数产生器
- 大数据---房地产大数据分析!
- 蝴蝶效应(Butterfly effect)[FROM 百度ZD]
- 华为核心交换机HW_S7706添加静态路由
- Pytorch图像预处理——归一化、标准化
- lucene高亮显示
- 【渝粤题库】陕西师范大学200791 软件工程
- java实现单链表就地逆置,20. 微软面试题:单链表就地逆放
- sap linux客户端,SAP 与 Linux类比