Java-链表(单向链表、双向链表)

Java-链表

1、什么是链表?

2、链表的特点是什么?

3、链表的实现原理?

4、如何自己写出一个链表?



1、什么是链表?

  • 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。
  • 每一个链表都包含多个节点,节点又包含两个部分,一个是数据域(储存节点含有的信息),一个是引用域(储存下一个节点或者上一个节点的地址)。
  • 链表的理解示意图

2、链表的特点是什么?

  • 获取数据麻烦,需要遍历查找,比数组慢
  • 方便插入、删除

3、链表的实现原理

  1. 创建一个节点类,其中节点类包含两个部分,第一个是数据域(你到时候要往节点里面储存的信息),第二个是引用域(相当于指针,单向链表有一个指针,指向下一个节点;双向链表有两个指针,分别指向下一个和上一个节点)
  2. 创建一个链表类,其中链表类包含三个属性:头结点、尾节点和大小,方法包含添加、删除、插入等等方法。

单向链表的节点类:

1 public class Node {
2     public Object data;
3     public Node next;
4
5     public Node(Object e){
6         this.data = e;
7     }
8 }

双向链表的节点类:

 1 public class Node {
 2     public Object e;
 3     public Node next;
 4     public Node pre;
 5     public Node(){
 6
 7     }
 8     public Node(Object e){
 9         this.e = e;
10         next = null;
11         pre = null;
12     }
13 }

4、如何自己写出一个链表?

代码如下(以双向链表为例,有详细的注释,单向链表同理):

首先创建了一个节点类

 1 package MutuLink;
 2
 3 public class Node {
 4     public Object e;
 5     public Node next;
 6     public Node pre;
 7     public Node(){
 8
 9     }
10     public Node(Object e){
11         this.e = e;
12         next = null;
13         pre = null;
14     }
15 }

然后创建了一个链表类

  1 package MutuLink;
  2
  3 public class MyList {
  4     private Node head;
  5     private Node tail;
  6     private int size = 0;
  7
  8     public MyList() {
  9         head = new Node();
 10         tail = new Node();
 11         head.next =null;
 12         tail.pre = null;
 13     }
 14
 15     public boolean empty() {
 16         if (head.next == null)
 17             return true;
 18         return false;
 19     }
 20     //找到所找下标节点的前一个节点
 21     public Node findpre(int index){
 22         Node rnode = head;
 23         int dex = -1;
 24         while(rnode.next != null){
 25             //找到了插入节点的上一个节点
 26             if( dex== index - 1){
 27                 return rnode;
 28             }
 29             rnode = rnode.next;
 30             dex++;
 31         }
 32         return null;
 33     }
 34     public Node findthis(int index){
 35         Node rnode = head;
 36         //把rnode想象为指针,dex为指向的下标,这个地方很容易错,因为当指向最后一个节点时没有判断IF就跳出循环了
 37         int dex = -1;
 38         while(rnode.next != null){
 39             if(dex == index)
 40             return rnode;
 41             rnode = rnode.next;
 42             dex++;
 43         }
 44         if(dex == size - 1){
 45             return rnode;
 46         }
 47 //        Node test = new Node(new Students("haha",1,2));
 48         return null;
 49     }
 50
 51     // 往链表末尾加入节点
 52     public void add(Object e) {
 53         Node node = new Node(e);
 54         Node rnode = head;
 55         //如果是空链表的话插入一个节点,这个节点的pre不能指向上一个节点,必须指空
 56         if (this.empty()) {
 57             rnode.next = node;
 58             rnode.next.pre = null;
 59             tail.pre = node;
 60             size++;
 61         } else {
 62             while (rnode.next != null)
 63                 rnode = rnode.next;
 64             rnode.next = node;
 65             node.pre = rnode;
 66             tail.pre = node;
 67             size++;
 68         }
 69     }
 70     //往链表的某一个标插入一个节点
 71     public boolean add(int index,Object e){
 72         if(index <0||index>=size)
 73             return false;
 74         Node node = new Node(e);
 75         Node prenode = this.findpre(index);
 76         node.next = prenode.next;
 77         prenode.next.pre = node;
 78         prenode.next = node;
 79         node.pre = prenode;
 80         size++;
 81         return true;
 82     }
 83     public boolean add(int index,MyList myl){
 84         if(index <0 || index >= size)
 85             return false;
 86         Node prenode = this.findpre(index);
 87 //        myl.tail.pre.next = prenode.next;
 88 //        prenode.pre = myl.tail.pre;
 89 //        tail.pre = null;
 90 //        prenode.next = myl.head.next;
 91 //        myl.head.next.pre = prenode;
 92 //        head.next = null;
 93         myl.tail.pre.next = prenode.next;
 94         prenode.next.pre = myl.tail.pre.pre;
 95         myl.head.next.pre = prenode.pre;
 96         prenode.next = myl.head.next;
 97         myl.head = null;
 98         myl.tail = null;
 99         size+=myl.size;
100         return true;
101     }
102
103     public Object remove(int index){
104         Object ob= this.get(index);
105         if(index <0 || index >= size)
106             return null;
107         //特殊情况,当移除节点是最后一个节点的时候
108         //较为复杂通过画图来写代码
109         if(index == size - 1){
110             Node prenode = this.findpre(index);
111             this.tail.pre = this.tail.pre.pre;
112             this.tail.pre.next.pre = null;
113             this.tail.pre.next =null;
114             size--;
115             return ob;
116         }
117         //比较复杂,通过画图解决
118         else{
119             Node prenode = this.findpre(index);
120             prenode.next = prenode.next.next;
121             prenode.next.pre.next = null;
122             prenode.next.pre = prenode.next.pre.pre;
123             size--;
124             return ob;
125         }
126     }
127
128
129     public Object get(int index){
130         Node thisnode = this.findthis(index);
131         return thisnode.e;
132     }
133     public int size(){
134         return size;
135     }
136 }

最后测试

 1 package MutuLink;
 2
 3 import java.util.Random;
 4
 5 public class manage {
 6     public static void main(String[] args) {
 7         String name = "";
 8         int credit;
 9         int age;
10         int size;
11         MyList myl = new MyList();
12         Random random = new Random();
13         size = random.nextInt(5) + 1;
14         for (int i = 0; i < size; i++) {
15             credit = random.nextInt(5);
16             age = random.nextInt(5) + 18;
17             for (int j = 0; j < 4; j++) {
18                 name += (char) (random.nextInt(26) + 97);
19             }
20             Students stu = new Students(name, credit, age);
21             myl.add(stu);
22             name = "";
23         }
24
25         System.out.println("Size of myl1 is "+ myl.size());
26         for(int i = 0; i < myl.size() ;i++){
27             Students stu2 = (Students) myl.get(i);
28             stu2.show();
29         }
30 //        //测试能否在链表末尾加入节点(成功)
31 //        for(int i = 0; i < myl.size() ;i++){
32 //            Students stu2 = (Students) myl.get(i);
33 //            stu2.show();
34 //        }
35 //        //测试能否通过下标加入一个节点(成功)
36 //        Students stu3 = new Students("cyt",5,18);
37 //        myl.add(1, stu3);
38 //        System.out.println("Size is "+ myl.size());
39 //        for(int i = 0; i < myl.size() ;i++){
40 //            Students stu2 = (Students) myl.get(i);
41 //            stu2.show();
42 //        }
43
44         MyList myl2 = new MyList();
45         size = random.nextInt(5) + 1;
46         for (int i = 0; i < size; i++) {
47             credit = random.nextInt(5);
48             age = random.nextInt(5) + 18;
49             for (int j = 0; j < 4; j++) {
50                 name += (char) (random.nextInt(26) + 97);
51             }
52             Students stu2 = new Students(name, credit, age);
53             myl2.add(stu2);
54             name = "";
55         }
56         System.out.println("Size is of myl2 "+ myl2.size());
57         for(int i = 0; i < myl2.size() ;i++){
58             Students stu2 = (Students) myl2.get(i);
59             stu2.show();
60         }
61
62
63
64         myl.add(1, myl2);
65         System.out.println("Size is of myl1 "+ myl.size());
66         for(int i = 0; i < myl.size() ;i++){
67             Students stu2 = (Students) myl.get(i);
68             stu2.show();
69         }
70
71
72     }
73
74 }

结果输出:

这样,一个简单的双向链表就编写完成了,希望这篇博客对您有所帮助哦!

原文地址:https://www.cnblogs.com/782687539-nanfu/p/10333031.html

时间: 2024-08-02 23:41:45

Java-链表(单向链表、双向链表)的相关文章

数据结构——Java实现单向链表

结点类: 1 /** 2 * @author zhengbinMac 3 * 一个OnelinkNode类的对象只表示链表中的一个结点,通过成员变量next的自引用方式实现线性表中各数据元素的逻辑关系. 4 */ 5 public class OnelinkNode { 6 // 保存结点的值 7 public int data; 8 // 保存后继结点的引用 9 public OnelinkNode next; 10 // 构造值为k的结点 11 public OnelinkNode(int

Java实现单向链表

/* 先定义一个Node类用来存储节点的值域和指针域 * 即当前节点中的值和后面节点的方法 * 在C中就是相当与定义一个结构体类型一个数据域和指针域的方法 */class LNode{//这个写法已经非常固定了 设置两个属性分别用set函数和get函数来得到这两个属性 private int data; private LNode next;//这个和String应该比较相似的用法,类名用来表示数据类型,表示next的数据类型也是节点 public void setData(int data){

Java实现单向链表反转

环境: Java: jdk1.8.0_91 public class LinkedListTest { public static void main(String[] args) { Node A = new Node("A"); Node B = new Node("B"); Node C = new Node("C"); Node D = new Node("D"); Node E = new Node("E&

Java实现单向链表的增删改查

class Node { public int val; public Node next; public Node(int val) { this.val = val; } } class ListHead { public int count ; public Node next; public ListHead() { this.count = 0; this.next = null; } } class List { public ListHead head; private Node

python数据结构链表之单向链表

本文和大家分享的主要是python中单向链表相关内容,一起来看看吧,希望对大家学习python有所帮助. 单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. . 表元素域elem用来存放具体的数据. . 链接域next用来存放下一个节点的位置(python中的标识) . 变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点. 节点实现 class 

数据结构-线性表之单向链表--一点一滴

单向链表 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始. 单向链表的数据结构可以分为两部分:数据域和指针域,数据域存储数据,指针域指向下一个储存节点的地址.分为动态单向链表和静态单向链表.单向链表也可以根据是否带头节点分为带头节点结构和无带头节点结构.我们把指向单链表的指针为头指针.头指针所指的不存放数据元素的第一个节点称作头节点.存放数据元素的节点成为第一个数据元素节点. 注:第一个数据元素节点在带头节点单链表中是第二个节点:而在不带头节

Python3中定义一个单向链表

链表是由节点构成的,一个指针代表一个方向,如果一个构成链表的节点都只包含一个指针,那么这个链表就是单向链表. 单向链表中的节点不光有代表方向的指针变量,也有值变量.所以我们定义链表,就是要定义链表中的节点,对链表的操作最后也就是对节点的操作. 这些包含数据的节点们在一种指定的结构下连接起来,成为了一种数据结构——单向链表.以上是我对单向链表的理解. 以下是我用python3对单向链表这种数据结构的一种实现: ''' Python3版单向链表-单向链表简称单链表 单链表中所包含的基本操作: 初始化

3-1单向链表

链表 为什么需要链表 顺序表的构建需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁,所以使用起来并不是很灵活. 链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理. 链表的定义 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址). 单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域

05-2_单向链表

单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. 表元素域elem用来存放具体的数据. 链接域next用来存放下一个节点的位置(python中的标识) 变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点. 单链表节点的实现 class SingleNode(object): """单链表的节点""&quo

【转】单向链表(单链表)的Java实现

最近被问到链表,是一个朋友和我讨论Java的时候说的.说实话,我学习编程的近一年时间里,学到的东西还是挺少的.语言是学了Java和C#,关 于Web的学了一点Html+css+javascript.因为比较偏好,学习WinForm时比较认真,数据库操作也自己有所研究.但链表这个东西我 还真没有学习和研究过,加上最近自己在看WPF,而课程也到了JSP了,比较紧. 但是我还是抽了一个晚上加半天的时间看了一下单向链表.并且使用Java试着写了一个实例出来.没有接触过链表的朋友可以作为参考,希望大家多提