Java链表的基本使用
链表是一种根据元素节点逻辑关系排列起来的一种数据结构。利用链表可以保存多个数据,这一点类似于数组的概念,但是数组本身有一个缺点—— 数组的长度固定,不可改变,在长度固定的情况下首选的肯定是数组,但是在现实的开发之中往往要保存的内容长度是不确定的,那么此时就可以利用链表这样的结构来代替数组的使用。
链表是一种最为简单的数据结构,它的主要目的是依靠引用关系来实现多个数据的保存。
下面是定义一个简单的类用来保存节点关系,并将所有节点链接起来。
例子1:
//每一个链表实际上就是由多个节点组成的
class Node { private String data; //用于保存数据private Node next; //用于保存下一个节点public Node(String data){ //每一个Node类对象都必须保存有数据this.data = data ;}public void setNext(Node next){this.next = next ;}public Node getNext(){return this.next ;}public String getData(){return this.data ;}
}public class LinkedList {public static void main(String[] args) {//第一步:准备数据Node root = new Node("火车头") ;Node n1 = new Node("车厢A") ;Node n2 = new Node("车厢B") ;// 链接节点root.setNext(n1);n1.setNext(n2);//第二步:取出所有数据Node currentNode = root ; //从当前根节点开始读取while( currentNode != null){System.out.println(currentNode.getData()) ;//将下一个节点设置为当前节点scurrentNode = currentNode.getNext() ;}}
}
运行:
火车头
车厢A
车厢B
例子2:
在进行链表操作的时候,首先需要的是一个根节点(第一个节点即为根节点),之后每一个节点的引用都保存在上一节点的next属性之中,而在进行输出的时候也应该按照节点的先后顺序,一个一个取得每一个节点所包装的数据。
public class LinkedList {public static void main(String[] args) {Link link = new Link() ;link.add("hello"); //增加节点link.add("world");link.add("wwww");link.print(); //打印数据 }
}//每一个链表实际上就是由多个节点组成的
class Node { private String data; // 用于保存数据private Node next; // 用于保存下一个节点public Node(String data) { // 每一个Node类对象都必须保存有响应的数据this.data = data;}public void setNext(Node next) {this.next = next;}public Node getNext() {return this.next;}public String getData() {return this.data;}// 实现节点的添加:// 第一次调用(Link):this代表Link.root// 第二次调用(Node):this代表Link.root.next// 第三次调用(Node):this代表Link.root.next.nextpublic void addNode(Node oldNode,Node newNode) { System.out.println("now:"+oldNode);if (this.next == null) { // 保存新节点this.next = newNode; } else { // 当前节点后面还有节点 this.next.addNode(this.next,newNode); // 当前节点的下一个节点继续保存,这里采用的是递归添加节点}System.out.println(oldNode+"=>"+this.next);}// 第一次调用(Link):this代表Link.root// 第二次调用(Node):this代表Link.root.next// 第三次调用(Node):this代表Link.root.next.nextpublic void printNode() {System.out.println("pp:"+this.data);// 输出当前数据if (this.next != null) { // 如果还有下一个节点,输出下一节点this.next.printNode(); // 递归打印节点,注意这里的this.next中的this指代}}
}// 链表增加节点,输出节点数据
class Link {private Node root; //新建根节点public void add (String data){Node newNode = new Node(data); //链表中新增节点类对象 if(this.root == null ){ // 如果链表还没有任何节点,就添加第一个节点作为根节点this.root = newNode; System.out.println("root:"+this.root);}else{ System.out.println("new:"+newNode);this.root.addNode(this.root,newNode); //从根节点节点新链接一个节点}}//输出当前节点数据public void print(){if( this.root != null ){ this.root.printNode();}}}
运行:
root:test.Node@7852e922
new:test.Node@4e25154f
now:test.Node@7852e922
test.Node@7852e922=>test.Node@4e25154f
new:test.Node@70dea4e
now:test.Node@7852e922
now:test.Node@4e25154f
test.Node@4e25154f=>test.Node@70dea4e
test.Node@7852e922=>test.Node@4e25154f
pp:hello
pp:world
pp:wwww
例子3:
关键是构造一个类,里面包含一个指向下一个元素的对象(指向下一个元素的指针)
public class LinkedList{public static void main(String[] args){MyLinkedList linkedList = new MyLinkedList();System.out.println("-------start-------");System.out.println("ll:"+linkedList.listEm());for (int i=0;i<5;i++){ //新建链表linkedList.add(i+1);}System.out.println("mm:"+linkedList.listEm()); //打印链表for(int i=0;i<5;i++){ //删除链表System.out.println("remove:"+linkedList.remove());}System.out.println("kk:"+linkedList.listEm());System.out.println("-------end-------");}
}class Node<T> {Node<T> next;T element;public Node( Node<T> next, T element){this.next = next;this.element = element;}
}class MyLinkedList<T> {private int size ; Node<T> last; //指向list中最后一个元素 Node<T> first; //指向list中第一个元素 Node<T> currRead; //指向当前读取的元素 // 默认构造函数public MyLinkedList(){ this.size = 0;this.last = new Node(null,-1);this.first = last;this.currRead = first;}//往链表中添加数据(队尾添加数据) public void add(T element){Node<T> newNode = new Node<T>(null,element);this.last.next = newNode;this.last = newNode; // 引用平移if(size == 0){this.first = newNode;}size ++;}//移除链表中的数据(队头移除)public T remove(){if(size == 0){System.out.println("empty list ");this.currRead = this.first;return null;}T result = this.first.element;this.first = this.first.next;this.currRead = this.first;size--;return result;}//获取队列中的元素public T get(){if(this.currRead.next == null){this.setReadAgain();return this.currRead.element;}T result = this.currRead.element;this.currRead = this.currRead.next;return result;}//再次从头开始读取数据public void setReadAgain() {this.currRead = this.first;}public String listEm(){StringBuilder sb = new StringBuilder();for(int i=0;i<size;i++){T ele = this.get();sb.append(this.currRead.element + "-->");}return sb.toString();}//获取队列大小public int getSize(){return this.size;}}
运行:
-------start-------
ll:
mm:1-->2-->3-->4-->5-->
remove:1
remove:2
remove:3
remove:4
remove:5
kk:
-------end-------
例四:
public class LinkedList {public static void main(String [] args){ Link l=new Link(); mytype[] la; mytype dsome=new mytype("韩敏","dsome",21); mytype shao=new mytype("邵晓","john",45); mytype hua=new mytype("华晓风","jam",46); mytype duo=new mytype("余小风","duo",1000); mytype wang=new mytype("王秋","jack",21); mytype shi=new mytype("韩寒","bob",3000); mytype yu=new mytype("于冬","keven",30); l.add(dsome);//测试增加节点 l.add(shao); l.add(hua); l.add(wang); l.add(shi); l.add(duo); l.add(yu); System.out.println("链表长度:"+l.length());//链表长度la=l.toArray(); for(int i=0;i<la.length;i++){ System.out.println(la[i].getInfo()); } System.out.println("是否包含余小风:"+l.contains(duo)+"\n"); System.out.println("删除余小风后\n"); l.remove(duo); la=l.toArray(); for(int i=0;i<la.length;i++){ //转化为数组之后输出 System.out.println(la[i].getInfo()); } System.out.println("\n利用索引方法输出全部数据"); for(int i=0;i<l.length();i++){ System.out.println(l.get(i).getInfo()); } System.out.println("是否包含余小风:"+l.contains(duo)+"\n"); l.clean(); System.out.println("执行清空操作后链表长度: "+l.length()+"\t是否为空链表:"+l.isEmpty()); }
}class Link {//内部类 private class Node{ private Node next; private mytype data; public Node(mytype data){ this.data=data; } public void addNode(Node newNode){ //增加节点 if(this.next==null){ this.next=newNode; // 指向新的节点}else{ this.next.addNode(newNode); // 递归调用是为了让next引用指向新的节点} } public mytype getNode(int index){//按照角标返回数据 if(index==Link.this.foot++){ return this.data; }else{ return this.next.getNode(index); } } public boolean iscontain(mytype data){//判断是否含有该数据 if(this.data.equals(data)){ return true; }else{ if(this.next!=null){ return this.next.iscontain(data); }else{ return false; } } } public void removeNode(Node previous,mytype data){ //删除节点 if(this.data.equals(data)){ //this:下一个节点Bprevious.next=this.next; // this.next:节点B的下一个节点C,previous:节点A}else{ this.next.removeNode(this,data); //注意这里的this.next和this的区别:this.next是下一个节点B,this是当前节点A} } public void toArrayNode(){ //转化数组 Link.this.Larray[Link.this.foot ++]=this.data; //每个节点的数据添加到一个mytype []中if(this.next!=null){ this.next.toArrayNode(); } }
}//内部类定义完毕
private Node root;
private int count=0;
private int foot;
private mytype [] Larray;public void add(mytype data){ //增加节点 if(data==null){ System.out.print("增加数据失败,数据为空");//测试用 return; } Node newNode=new Node(data); //新建节点if(this.root==null){ this.root=newNode; this.count++; }else{ this.root.addNode(newNode); this.count++; } } public int length(){//链表长度 return this.count; } public boolean isEmpty(){//是否为空链表 if(this.count==0)return true; else return false; } public void clean(){//清空链表 this.root=null; this.count=0; } public mytype get(int index){//索引返回节点所存的数据 if(index>=this.count||index<0){ System.out.print("越界错误");//测试用 return null; }else{ this.foot=0; return this.root.getNode(index); } } public boolean contains(mytype data){ //判断链表数据是否含data if(data==null) return false;elsereturn this.root.iscontain(data); } public void remove(mytype data){ //删除指定数据节点 if(this.contains(data)){ if(this.root.data.equals(data)){ this.root=this.root.next; this.count--; } else{ this.count--; this.root.next.removeNode(root,data); } }else{ System.out.print("删除错误");//测试用 } } public mytype[] toArray(){ //把链表转化成对象数组 if(this.count==0){ return null; } this.foot=0; this.Larray=new mytype [this.count]; this.root.toArrayNode(); return this.Larray; }
}class mytype {private String name; private String people; private int age;public mytype(String name,String people,int age){//链表中的数据(可自定义) this.name=name; this.people=people; this.age=age; } public boolean equals(mytype data){//判断数据是否相同 if(this==data){ return true; } if(data==null){ return false; } if(this.name.equals(data.name)&&this.people.equals(data.people)&&this.age==data.age){ return true; }else{ return false; } }public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPeople() {return people;}public void setPeople(String people) {this.people = people;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} public String getInfo(){ return "名字 :"+this.name+"\n"+ "人物 :"+this.people+"\n"+ "年龄 :"+this.age; }
}
运行:
链表长度:7
名字 :韩敏
人物 :dsome
年龄 :21
名字 :邵晓
人物 :john
年龄 :45
名字 :华晓风
人物 :jam
年龄 :46
名字 :王秋
人物 :jack
年龄 :21
名字 :韩寒
人物 :bob
年龄 :3000
名字 :余小风
人物 :duo
年龄 :1000
名字 :于冬
人物 :keven
年龄 :30
是否包含余小风:true删除多余后名字 :韩敏
人物 :dsome
年龄 :21
名字 :邵晓
人物 :john
年龄 :45
名字 :华晓风
人物 :jam
年龄 :46
名字 :王秋
人物 :jack
年龄 :21
名字 :韩寒
人物 :bob
年龄 :3000
名字 :于冬
人物 :keven
年龄 :30利用索引方法输出全部数据
名字 :韩敏
人物 :dsome
年龄 :21
名字 :邵晓
人物 :john
年龄 :45
名字 :华晓风
人物 :jam
年龄 :46
名字 :王秋
人物 :jack
年龄 :21
名字 :韩寒
人物 :bob
年龄 :3000
名字 :于冬
人物 :keven
年龄 :30
是否包含多余:false执行清空操作后链表长度: 0 是否为空链表:true
参考:
https://blog.csdn.net/qq_37199582/article/details/79244657
https://blog.csdn.net/google_huchun/article/details/52824024
Java链表的基本使用相关推荐
- JAVA链表中迭代器的实现
注:本文代码出自<java数据结构和算法>一书. PS:本文中类的名字定义存在问题,Link9应改为Link.LinkList9应该为LinkList.由于在同包下存在该名称,所以在后面接 ...
- java 增 删 查 改_如何对java链表进行增、删、查、改操作
如何对java链表进行增.删.查.改操作 发布时间:2020-06-23 10:41:33 来源:亿速云 阅读:79 作者:Leah 如何对java链表进行增.删.查.改操作?针对这个问题,今天小编总 ...
- java链表奇数倒序偶数顺序_将链表中的所有元素为奇数的节点移到元素为偶数节点的前面,并保证奇数之间顺序不变,偶数之间顺序不变。...
2.将链表中的所有元素为奇数的节点移到元素为偶数节点的前面,并保证奇数之间顺序不变,偶数之间顺序不变. 示例: 交换前链表的顺序 交换后链表的顺序 4→5→3→1→2 == ...
- 对java 链表删除节点 引用误区理解:对局部变量 cur= cur.next及cur.next=cur.next.next,及cur.next = cur.next.next.next的理解图解
对java 链表删除节点 引用误区理解: 对java 链表删除节点 引用误区理解: 对局部变量 cur= cur.next及cur.next=cur.next.next,及cur.next = cur ...
- java链表list_java集合之linkedList链表基础
LinkedList链表: List接口的链接列表实现.允许存储所有元素(包含null).使用频繁增删元素. linkedList方法: void addFirst(E e) 指定元素插入列表的开头 ...
- java单链表例子_写一个java链表的例子?随便举例说一下。
展开全部 //单链表类 package dataStructure.linearList; import dataStructure.linearList.Node; //导入单链表结点类 impor ...
- java 链表 传递_java 链表 传递过程中的问题
具体情况如下一共有三个类,分别是主类main,从TXT文件中读取入链表的类read,还有一个是对链表内容进行查询的类inquiryread读取并没有问题,read中有加入检测M.List.add(A) ...
- java 链表反转_LeetCode206 实现单链表的反转
LeetCode206 实现单链表的反转 LeetCode 码,码不停题 1.题目介绍 Reverse a singly linked list. Example: Input:1->2-> ...
- Java链表—— LinkedList
ArrayList 相比,LinkedList 的增加和删除的操作效率更高,而查找和修改的操作效率较低. 链表LinkedList和动态数组ArrayList 以下情况使用 ArrayList : 频 ...
- java链表list_数据结构-List:使用Java实现双向链表LinkedList
JDK中的LinkedList属于双向循环链表. 下面是使用Java来实现一个双向非循环链表. package org.cgz.practice2; import java.util.NoSuchEl ...
最新文章
- 【WEB API项目实战干货系列】- API登录与身份验证(三)
- 为什么应该学习Kotlin
- 蓝桥杯 ADV-234 算法提高 字符串跳步
- python代码怎么练_自己练习的Python代码(1)
- Springer期刊LaTeX模板的一些问题
- IT前沿技术之node.js篇一:Node.js与javascript
- CSS3 页面布局
- 2016届毕业设计(论文) 基本规范及档案袋封面填写要求
- 用友U8V系统怎么重启服务器,用友u8怎么重启云服务器
- C# 一种英文日期格式转换
- kotlin java 知乎_GitHub - luciferldy/ZhihuDailyKotlin: 这是是一个使用 Kotlin 开发的知乎日报客户端...
- Ubuntu 18.04 安装 deepin 微信
- 计算机有没有32进制,32进制(32进制转换十进制)
- NXP MCU CAN波特率(位时间)配置详解
- Xcode11没有iOS14的真机包,Xcode12没有iOS8的真机包,用到的时候网上都要积分收费,免费的不好找,因此只有自己保存一份使用到的时候才不慌
- 今天是微信7周年 7年之痒 一切都已被改变
- STM32的AFIO时钟什么时候需要开启
- 使用pydicom和SimpleITK预处理dicom文件
- 基于Python的人脸识别方法
- Vue.js--下拉菜单组件
热门文章
- Qt Creator使用ClearCase
- C++qr decomposition 正交三角实现算法(附完整源码)
- QT的QFutureIterator类的使用
- 经典C语言程序100例之二九
- java 经典语录_JavaSpring过时的经典语录
- c语言整行乘非整形等于什么意思,C语言--整形升级寻常算术转换
- 「Anaconda」取消终端命令行自动加载的conda(base)虚拟环境
- NDK开发环境安装,CDT安装,Cygwin安装
- 求变量的数据类型,typeid,bool,C和C++的不同,new和delete,C++中的枚举,inline和可变参数模板,auto和函数模板,宽字符
- 基于注解的Spring MVC整合Hibernate(所需jar包,spring和Hibernate整合配置,springMVC配置,重定向,批量删除)