数据结构学习java(一点五)链式顺序表(链表)

java中没有将指针暴露给用户(以前做过看过一篇文章写有java中是有指针的,只是被藏起来了),所以得使用引用的方式。

何为引用请看下面这篇文章(写的很不错,当然肯定比我写的好):

https://www.cnblogs.com/huajiezh/p/5835618.html

链表中内部类和嵌套类的区别:

https://blog.csdn.net/WelcomeSpring/article/details/79430546

以下代码采用内部类。

 1  /**
 2      * 内部类
 3      * @param <E> 泛型
 4      */
 5     private class Node<E>{
 6         E data;
 7         Node<E> next;
 8         Node<E> pre;
 9         public Node(E data){
10             this.data=data;
11         }
12
13      public Node(E data, Node next, Node pre) {
14          this.data = data;
15          this.next = next;
16          this.pre = pre;
17      }
18      public Node(){
19         next=null;
20         pre=null;
21         data=null;
22      }
23      public E getData() {
24          return data;
25      }
26
27      public void setData(E data) {
28          this.data = data;
29      }
30
31      public Node getNext() {
32          return next;
33      }
34
35      public void setNext(Node next) {
36          this.next = next;
37      }
38
39      public Node getPre() {
40          return pre;
41      }
42
43      public void setPre(Node pre) {
44          this.pre = pre;
45      }
46  }

E data:存储对象的区域   Node<E> next:引用链表的下一个对象  Node<E> pre;引用链表的上一个对象 所构成了一个双链表

源代码:

  1 /**
  2  * @author 李正阳
  3  * @param <E> 泛型
  4  */
  5 public class MyLinkedList<E> implements List<E> {
  6
  7     private Node<E> head=new Node<>();
  8     private int size=0;
  9
 10     /**
 11      * 在链表的最后插入元素
 12      * @param data 插入的元素
 13      * @return true 插入成功
 14      */
 15     @Override
 16     public boolean add(E data) {
 17         Node<E> pNode= head;
 18         while (pNode.getNext()!=null){
 19             pNode=pNode.next;
 20         }
 21         Node<E> temp=new Node(data);
 22         temp.setPre(pNode);
 23         pNode.setNext(temp);
 24         size++;
 25         return true;
 26     }
 27
 28     /**
 29      *在number位置添加一个元素
 30      * @param number 在链表中的位置(不是从0开始)
 31      * @return true 添加成功
 32      */
 33     @Override
 34     public boolean add(int number,E data){
 35         Node<E> pNode=head;
 36         Node<E> temp=new Node<>(data);
 37         for (int i=0;i<number;i++){
 38            pNode= pNode.getNext();
 39         }
 40         pNode.getPre().setNext(temp);
 41         temp.setPre(pNode.getPre());
 42         temp.setNext(pNode.getNext());
 43         pNode.getNext().setPre(temp);
 44         return true;
 45     }
 46     /**
 47      * 判空函数
 48      * @return true 链表为空 false 链表不为空
 49      */
 50     @Override
 51     public boolean isEmpty() {
 52         if(head.getNext()==null){
 53             return true;
 54         }else {
 55             return false;
 56         }
 57     }
 58
 59     /**
 60      * 删除链表中number位置的元素
 61      * @param number 元素在链表中的位置
 62      * @return 删除的那个元素
 63      */
 64     @Override
 65     public E remove(int number) {
 66         E temp;
 67         Node<E> pNode,preNode;
 68         pNode=head;
 69         for(int i=0;i<number;i++){
 70             pNode=pNode.next;
 71         }
 72         temp=(E) pNode.getData();
 73         preNode=pNode.getPre();
 74         preNode.setNext(pNode.getNext());
 75         pNode.getNext().setPre(preNode);
 76         pNode.setNext(null);
 77         pNode.setPre(null);
 78         pNode=null;
 79         return temp;
 80     }
 81
 82     /**
 83      * 尾删法
 84      * @return 删除的那个元素
 85      */
 86     @Override
 87     public E remove() {
 88         E temp;
 89         Node<E> pNode,preNode;
 90         pNode=head;
 91         while (pNode.getNext()!=null){
 92             pNode=pNode.next;
 93         }
 94         temp=(E) pNode.getData();
 95         preNode=pNode.getPre();
 96         preNode.setNext(null);
 97         pNode.setNext(null);
 98         pNode.setPre(null);
 99         pNode=null;
100         return temp;
101     }
102
103     /**
104      * 将第i位置的元素替换
105      * @param i 元素在链表中的位置
106      * @param data 替换的元素
107      */
108     @Override
109     public void set(int i, E data) {
110         Node<E> pNode=head;
111         for (int j=0;j<i;j++){
112             pNode=pNode.getNext();
113         }
114         pNode.setData(data);
115     }
116
117     /**
118      * 获得链表在i位置的元素
119      * @param i 元素在i位置的元素
120      * @return i位置的元素
121      */
122     @Override
123     public E get(int i) {
124         E temp;
125         Node<E> pNode=head;
126         for (int j=0;j<i;j++){
127             pNode=pNode.getNext();
128         }
129         temp=(E) pNode.getData();
130         return temp;
131     }
132
133     /**
134      * 检查这条链表现有的是否为回文
135      * @return true 为回文 false 不为回文
136      */
137     @Override
138     public boolean isPalindrome() {
139         Node<E> pNode,nNode;
140         pNode=head.getNext();
141         nNode=head;
142         while (nNode.getNext()!=null){
143             nNode=nNode.getNext();
144         }
145        StringBuilder posSequence=new StringBuilder();
146         StringBuilder revOrder=new StringBuilder();
147         while(pNode.getNext()!=null) {
148             posSequence.append(pNode.getData());
149             pNode=pNode.getNext();
150         }
151         posSequence.append(pNode.getData());
152         while (nNode.getPre()!=null){
153             revOrder.append(nNode.getData());
154             nNode=nNode.getPre();
155         }
156        String posequence=posSequence.toString();
157         String revoredr=revOrder.toString();
158         if(posequence.equals(revoredr)) {
159             return true;
160         }else {
161             return false;
162         }
163     }
164
165     /**
166      * 倒置链表
167      */
168     @Override
169     public void reverseList(){
170         Node<E> node,nNode;
171         node=head.getNext();
172         node.setPre(node.getNext());
173         node=node.getNext();
174         nNode=node.getNext();
175         head.getNext().setNext(null);
176         while (nNode!=null) {
177             node.setNext(node.getPre());
178             node.setPre(nNode);
179             node=node.getPre();
180             nNode=node.getNext();
181         }
182         node.setNext(node.getPre());
183         node.setPre(head);
184         head.setNext(node);
185     }
186     /**
187      * 头插法
188      * @param data 插入的元素
189      * @return true 添加成功 false 添加失败
190      */
191     @Override
192     public boolean addFirst(E data){
193         Node<E> node=new Node(data);
194         Node<E> preNode=head.getNext();
195         head.setNext(node);
196         preNode.setPre(node);
197         node.setNext(preNode);
198         node.setPre(head);
199         return true;
200     }
201
202     /**
203      * 遍历并输出链表中的元素
204      */
205     @Override
206     public void traver() {
207         if(isEmpty()){
208             System.out.println("链表为空");
209         }else {
210             Node<E> pNode = head.getNext();
211             while (pNode != null) {
212                 System.out.print(pNode.getData() + " ");
213                 pNode = pNode.getNext();
214             }
215         }
216     }
217
218     /**
219      * 内部类
220      * @param <E> 泛型
221      */
222     private class Node<E>{
223         E data;
224         Node<E> next;
225         Node<E> pre;
226         public Node(E data){
227             this.data=data;
228         }
229
230      public Node(E data, Node next, Node pre) {
231          this.data = data;
232          this.next = next;
233          this.pre = pre;
234      }
235      public Node(){
236         next=null;
237         pre=null;
238         data=null;
239      }
240      public E getData() {
241          return data;
242      }
243
244      public void setData(E data) {
245          this.data = data;
246      }
247
248      public Node getNext() {
249          return next;
250      }
251
252      public void setNext(Node next) {
253          this.next = next;
254      }
255
256      public Node getPre() {
257          return pre;
258      }
259
260      public void setPre(Node pre) {
261          this.pre = pre;
262      }
263  }
264
265 }

检查链表所存储是否为回文:

 1     /**
 2      * 检查这条链表现有的是否为回文
 3      * @return true 为回文 false 不为回文
 4      */
 5     @Override
 6     public boolean isPalindrome() {
 7         Node<E> pNode,nNode;
 8         pNode=head.getNext();
 9         nNode=head;
10         while (nNode.getNext()!=null){
11             nNode=nNode.getNext();
12         }
13        StringBuilder posSequence=new StringBuilder();
14         StringBuilder revOrder=new StringBuilder();
15         while(pNode.getNext()!=null) {
16             posSequence.append(pNode.getData());
17             pNode=pNode.getNext();
18         }
19         posSequence.append(pNode.getData());
20         while (nNode.getPre()!=null){
21             revOrder.append(nNode.getData());
22             nNode=nNode.getPre();
23         }
24        String posequence=posSequence.toString();
25         String revoredr=revOrder.toString();
26         if(posequence.equals(revoredr)) {
27             return true;
28         }else {
29             return false;
30         }
31     }
* 算法设计:比较粗暴,直接从链表头到尾将值组成一个String* 从链表尾到头将值组成一个String* 然后比较这两个字符串是否相等链表倒置:
 1   /**
 2      * 倒置链表
 3      * 算法设计
 4      */
 5     @Override
 6     public void reverseList(){
 7         Node<E> node,nNode;
 8         node=head.getNext();
 9         node.setPre(node.getNext());
10         node=node.getNext();
11         nNode=node.getNext();
12         head.getNext().setNext(null);
13         while (nNode!=null) {
14             node.setNext(node.getPre());
15             node.setPre(nNode);
16             node=node.getPre();
17             nNode=node.getNext();
18         }
19         node.setNext(node.getPre());
20         node.setPre(head);
21         head.setNext(node);
22     }
* 算法设计:倒置链表需要修改三处地方,* 头结点变成尾节点:将pre赋值尾next的引用,next赋值为null* 尾节点变成头结点:将next赋值为pre,pre赋值为null* 中间节点将next设置为pre,next设置为pre


原文地址:https://www.cnblogs.com/lzy321/p/10371767.html

时间: 2024-11-01 21:54:54

数据结构学习java(一点五)链式顺序表(链表)的相关文章

java实现的链式线性表结构

package com.hephec.ds; public class LinkedList<T> { //定义一个内部类节点Node Node实例代表链表的节点 class Node{ //保存节点的数据 private T data; //保存下一个节点的引用 private Node next; //无参的构造方法 public Node(){ } //有参的构造方法 public Node(T data,Node next){ this.data=data; this.next=nex

数据结构学习之堆栈(链式存储)

[摘要]链表存储结构的内存地址不一定是连续的,但顺序存储结构的内存地址一定是连续的:链式存储适用于在较频繁地插入.删除.更新元素时,而顺序存储结构适用于频繁查询时使用.所以本文主要基于前文的基础,讨论链式存储结构的堆栈. 1.链式存储(不连续内存) /*链式结构*/ typedef struct _STACK_NODE { int pData; struct _STACK_NODE *next; }STACK_NODE,*LinkStackPtr; typedef struct LinkStac

数据结构第一次作业(学生信息管理系统-顺序表&amp;&amp;链表)

实验目的 : 1 .掌握线性表的定义: 2 .掌握线性表的基本操作,如建立.查找.插入和删除等. 实验内容: 定义一个包含学生信息(学号,姓名,成绩)的的 顺序表和链表,使其具有如下功能: (1) 根据指定学生个数,逐个输入学生信息: (2) 逐个显示学生表中所有学生的相关信息: (3) 根据姓名进行查找,返回此学生的学号和成绩: (4) 根据指定的位置可返回相应的学生信息(学号,姓名,成绩): (5) 给定一个学生信息,插入到表中指定的位置: (6) 删除指定位置的学生记录: (7) 统计表中

如何学习Swift可空链式调用

今天我们一起来学习Swift可空链式调用.可空链式调用是一种可以请求和调用属性.方法以及下标的过程,它的可空体现在请求或调用的目标当前可能为nil.如果可空的目标有值,即调用就会成功:如果选择的目标为nil,即调用将返回nil.多个连续的调用可以被链接在一起形成一个调用链,如果其中任何一个节点为nil将导致整个链调用失败.    一.使用可空链式调用来强制展开    可空链的定义,即是在要调用非空的属性.方法.下标的可空值后面添加一个问号即可.特别的,可空链式调用的返回结果与原本的返回结果具有相

java中的链式编程

听到链式编程听陌生的,但是写出来就感觉其实很熟悉 1 package test; 2 3 public class Test { 4 String name; 5 String phone; 6 String mail; 7 String sex; 8 public Test setName(String name) { 9 this.name = name; 10 return this; 11 } 12 public Test setPhone(String phone) { 13 this

数据结构(四)——基于链式存储结构的线性表

数据结构(四)--基于链式存储结构的线性表 一.基于链式存储结构的线性表 1.链式存储的定义 链式存储为了表示数据元素与其直接后继元素间的逻辑关系,数据元素除了存储本身的信息外,还需要存储直接后继的信息.相连的数据元素之间在存储空间中不要求连续.链式存储的逻辑结构基于链式存储结构的线性表中,每个结点都包含数据域和指针域.数据域用于存储数据元素本身,指针域用于存储相邻结点的地址. 2.链表的定义 链表是基于链式存储结构的线性表链表的基本元素:头结点:链表中的辅助结点,包含指向第一个数据元素的指针数

(郝斌讲学)数据结构学习篇(五)---队列的CRUD操作

队列 什么是队列? 一种可以实现"先进先出"的存储结构. 出队  入队  -->>队列 出栈  压栈  -->>栈 链式队列 ---用链表实现的 静态队列 ---用数组实现的 静态队列通常必须是循环队列.. 039.循环队列需要几个参数来确定极其含义的讲解 front代表的是队列的第一个元素 rear代表的是队列的最后一个有效元素的下一个元素 队列为空: front和rear的值相等,但不一定为零 队列初始化 front和rear的值都是零. 循环队列入队的伪算

双向链式线性表(模板实现)

线性表(List):零个或者多个数据元素的有限序列. 线性表的存储结构大约分为三种:1,顺序存储结构 2,链式存储结构 3,静态链表. 顺序存储结构的线性表是由数组实现的,由于C++不支持变长数组,所以顺序存储结构的线性表在定义时就指定了长度,这是一个很大的问题.譬如说,一个顺序存储结构的线性表的长度为10000,我们写程序用到了这个线性表,但是只往表里添加了十几个数据,这显然对空间造成了极大的浪费.所以说,这种结构的线性表并适用于实际的应用. 链式存储结构的线性表实现了空间的动态分配,这一概念

链式线性表实现

1.链式线性表头文件 #ifndef _LINK_LIST_H #define _LINK_LIST_H //定义一个节点 typedef struct _tag_LinkListNode { _tag_LinkListNode *next; }LinkListNode; //定义一个链表@1链表包含一个头部节点@ 包含链表的长度 typedef struct _LinkList { LinkListNode Head; int nLen;//长度 }LinkList; LinkList *li