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

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

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

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

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

以下代码采用内部类。

  /**
* 内部类
* @param <E> 泛型
*/
private class Node<E>{
E data;
Node<E> next;
Node<E> pre;
public Node(E data){
this.data=data;
} public Node(E data, Node next, Node pre) {
this.data = data;
this.next = next;
this.pre = pre;
}
public Node(){
next=null;
pre=null;
data=null;
}
public E getData() {
return data;
} public void setData(E data) {
this.data = data;
} public Node getNext() {
return next;
} public void setNext(Node next) {
this.next = next;
} public Node getPre() {
return pre;
} public void setPre(Node pre) {
this.pre = pre;
}
}

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

源代码:

 /**
* @author 李正阳
* @param <E> 泛型
*/
public class MyLinkedList<E> implements List<E> { private Node<E> head=new Node<>();
private int size=0; /**
* 在链表的最后插入元素
* @param data 插入的元素
* @return true 插入成功
*/
@Override
public boolean add(E data) {
Node<E> pNode= head;
while (pNode.getNext()!=null){
pNode=pNode.next;
}
Node<E> temp=new Node(data);
temp.setPre(pNode);
pNode.setNext(temp);
size++;
return true;
} /**
*在number位置添加一个元素
* @param number 在链表中的位置(不是从0开始)
* @return true 添加成功
*/
@Override
public boolean add(int number,E data){
Node<E> pNode=head;
Node<E> temp=new Node<>(data);
for (int i=0;i<number;i++){
pNode= pNode.getNext();
}
pNode.getPre().setNext(temp);
temp.setPre(pNode.getPre());
temp.setNext(pNode.getNext());
pNode.getNext().setPre(temp);
return true;
}
/**
* 判空函数
* @return true 链表为空 false 链表不为空
*/
@Override
public boolean isEmpty() {
if(head.getNext()==null){
return true;
}else {
return false;
}
} /**
* 删除链表中number位置的元素
* @param number 元素在链表中的位置
* @return 删除的那个元素
*/
@Override
public E remove(int number) {
E temp;
Node<E> pNode,preNode;
pNode=head;
for(int i=0;i<number;i++){
pNode=pNode.next;
}
temp=(E) pNode.getData();
preNode=pNode.getPre();
preNode.setNext(pNode.getNext());
pNode.getNext().setPre(preNode);
pNode.setNext(null);
pNode.setPre(null);
pNode=null;
return temp;
} /**
* 尾删法
* @return 删除的那个元素
*/
@Override
public E remove() {
E temp;
Node<E> pNode,preNode;
pNode=head;
while (pNode.getNext()!=null){
pNode=pNode.next;
}
temp=(E) pNode.getData();
preNode=pNode.getPre();
preNode.setNext(null);
pNode.setNext(null);
pNode.setPre(null);
pNode=null;
return temp;
} /**
* 将第i位置的元素替换
* @param i 元素在链表中的位置
* @param data 替换的元素
*/
@Override
public void set(int i, E data) {
Node<E> pNode=head;
for (int j=0;j<i;j++){
pNode=pNode.getNext();
}
pNode.setData(data);
} /**
* 获得链表在i位置的元素
* @param i 元素在i位置的元素
* @return i位置的元素
*/
@Override
public E get(int i) {
E temp;
Node<E> pNode=head;
for (int j=0;j<i;j++){
pNode=pNode.getNext();
}
temp=(E) pNode.getData();
return temp;
} /**
* 检查这条链表现有的是否为回文
* @return true 为回文 false 不为回文
*/
@Override
public boolean isPalindrome() {
Node<E> pNode,nNode;
pNode=head.getNext();
nNode=head;
while (nNode.getNext()!=null){
nNode=nNode.getNext();
}
StringBuilder posSequence=new StringBuilder();
StringBuilder revOrder=new StringBuilder();
while(pNode.getNext()!=null) {
posSequence.append(pNode.getData());
pNode=pNode.getNext();
}
posSequence.append(pNode.getData());
while (nNode.getPre()!=null){
revOrder.append(nNode.getData());
nNode=nNode.getPre();
}
String posequence=posSequence.toString();
String revoredr=revOrder.toString();
if(posequence.equals(revoredr)) {
return true;
}else {
return false;
}
} /**
* 倒置链表
*/
@Override
public void reverseList(){
Node<E> node,nNode;
node=head.getNext();
node.setPre(node.getNext());
node=node.getNext();
nNode=node.getNext();
head.getNext().setNext(null);
while (nNode!=null) {
node.setNext(node.getPre());
node.setPre(nNode);
node=node.getPre();
nNode=node.getNext();
}
node.setNext(node.getPre());
node.setPre(head);
head.setNext(node);
}
/**
* 头插法
* @param data 插入的元素
* @return true 添加成功 false 添加失败
*/
@Override
public boolean addFirst(E data){
Node<E> node=new Node(data);
Node<E> preNode=head.getNext();
head.setNext(node);
preNode.setPre(node);
node.setNext(preNode);
node.setPre(head);
return true;
} /**
* 遍历并输出链表中的元素
*/
@Override
public void traver() {
if(isEmpty()){
System.out.println("链表为空");
}else {
Node<E> pNode = head.getNext();
while (pNode != null) {
System.out.print(pNode.getData() + " ");
pNode = pNode.getNext();
}
}
} /**
* 内部类
* @param <E> 泛型
*/
private class Node<E>{
E data;
Node<E> next;
Node<E> pre;
public Node(E data){
this.data=data;
} public Node(E data, Node next, Node pre) {
this.data = data;
this.next = next;
this.pre = pre;
}
public Node(){
next=null;
pre=null;
data=null;
}
public E getData() {
return data;
} public void setData(E data) {
this.data = data;
} public Node getNext() {
return next;
} public void setNext(Node next) {
this.next = next;
} public Node getPre() {
return pre;
} public void setPre(Node pre) {
this.pre = pre;
}
} }

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

     /**
* 检查这条链表现有的是否为回文
* @return true 为回文 false 不为回文
*/
@Override
public boolean isPalindrome() {
Node<E> pNode,nNode;
pNode=head.getNext();
nNode=head;
while (nNode.getNext()!=null){
nNode=nNode.getNext();
}
StringBuilder posSequence=new StringBuilder();
StringBuilder revOrder=new StringBuilder();
while(pNode.getNext()!=null) {
posSequence.append(pNode.getData());
pNode=pNode.getNext();
}
posSequence.append(pNode.getData());
while (nNode.getPre()!=null){
revOrder.append(nNode.getData());
nNode=nNode.getPre();
}
String posequence=posSequence.toString();
String revoredr=revOrder.toString();
if(posequence.equals(revoredr)) {
return true;
}else {
return false;
}
}
* 算法设计:比较粗暴,直接从链表头到尾将值组成一个String
* 从链表尾到头将值组成一个String
* 然后比较这两个字符串是否相等
链表倒置:
   /**
* 倒置链表
* 算法设计
*/
@Override
public void reverseList(){
Node<E> node,nNode;
node=head.getNext();
node.setPre(node.getNext());
node=node.getNext();
nNode=node.getNext();
head.getNext().setNext(null);
while (nNode!=null) {
node.setNext(node.getPre());
node.setPre(nNode);
node=node.getPre();
nNode=node.getNext();
}
node.setNext(node.getPre());
node.setPre(head);
head.setNext(node);
}
* 算法设计:倒置链表需要修改三处地方,
* 头结点变成尾节点:将pre赋值尾next的引用,next赋值为null
* 尾节点变成头结点:将next赋值为pre,pre赋值为null
* 中间节点将next设置为pre,next设置为pre
												

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

  1. python数据结构与算法第五天【顺序表】

    1.列表存储的两种方式 (1)元素内置方式 采用元素内置的方式只能存放同类型元素的数据类型,例如列表中的元素都为整形,元素类型相同,每个元素存放的地址空间大小也相同,则列表中每个元素都是顺序存放的 ( ...

  2. 7-19 求链式线性表的倒数第K项

    7-19 求链式线性表的倒数第K项(20 分) 给定一系列正整数,请设计一个尽可能高效的算法,查找倒数第K个位置上的数字. 输入格式: 输入首先给出一个正整数K,随后是若干正整数,最后以一个负整数表示 ...

  3. C语言- 基础数据结构和算法 - 栈的链式存储

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  4. javascript学习(10)——[知识储备]链式调用

    上次我们简单的说了下单例的用法,这个也是在我们java中比较常见的设计模式. 今天简单说下链式调用,可能有很多人并没有听过链式调用,但是其实只要我简单的说下的话,你肯定基本上都在用,大家熟知的jQue ...

  5. guoshiyv 数据结构与算法2-1 线性链式存储

    线性链式存储:   包含两部分:1.存储的单个元素 2.指针,指向下一个的地址 typedef struct() { ElementType Data; struct Node *Next; }Lis ...

  6. 系统学习 Java IO (五)----使用 SequenceInputStream 组合多个流

    目录:系统学习 Java IO---- 目录,概览 SequenceInputStream 可以将两个或多个其他 InputStream 合并为一个. 首先,SequenceInputStream 将 ...

  7. swift学习笔记之-可选链式调用

    //可选链式调用 import UIKit /*可选链式调用(Optional Chaining) 1.在可选值上请求和调用该可选值的属性.方法及下标的方法,如果可选值有值,那么调用就会成功,返回可选 ...

  8. java中的链式编程

    听到链式编程听陌生的,但是写出来就感觉其实很熟悉 package test; public class Test { String name; String phone; String mail; S ...

  9. Java 中的链式编程

    前言 ​ 在写项目的时候,有一个实体类有好多个属性,new 出来之后需要不停的使用setXXX( )方法,效率低而且代码可读性差,查询了下发现可以实现实体类的链式编程. public class Us ...

随机推荐

  1. video 属性和事件用法大全

    1.video 属性 <!-- video 不支持 IE8及以下版本浏览器,支持三种视频格式:MP4,WebM 和 Ogg --> <video src="test.mp4 ...

  2. SpringBoot + Spring Security 学习笔记(五)实现短信验证码+登录功能

    在 Spring Security 中基于表单的认证模式,默认就是密码帐号登录认证,那么对于短信验证码+登录的方式,Spring Security 没有现成的接口可以使用,所以需要自己的封装一个类似的 ...

  3. Java基础练习2(构造方法)

    1.以下关于面向对象概念的描述中,不正确的一项是() A.在构造方法中,this()只能出现在构造方法第一行位置 B.在构造方法中,super()只能出现在构造方法第一行位置 C.this()和sup ...

  4. 开发时候常用的js方法封装

    1.判断是否是一个数组 function isArray(arr){ return Object.prototype.toString.call(arr) ==='[object Array]'; } ...

  5. 项目中git分支管理策略

  6. Win10常见问题记录

    基本信息 记录我在使用win10过程中遇到的一些问题 我所使用的两个win10系统 Win10 企业版 1607(家里电脑) Win10 专业版 1806(公司电脑) win10 开启Sets 请问您 ...

  7. 如何用RSS订阅?

    本文由云+社区发表 摘要:我们常常会有订阅别人文章的需求,有更新的时候希望能有提醒的功能,RSS就是这样一个订阅的方式.很多网站上看到RSS的入口,点进去以后总是显示一堆的XML代码,我们来看看怎么使 ...

  8. 3. [leetcode] Longest Substring Without Repeating Characters

    Given a string, find the length of the longest substring without repeating characters. Examples Give ...

  9. RocketMQ4.4.0新特性分享

    rocketmq1.架构 MQ历史 由数据结构队列发展而来 MQ使用场景 异步处理 解耦 削峰填谷 数据同步2.队列3.使用 生产 同步(sync) 默认重试2次总共3次 默认等待超时时间为3s 异步 ...

  10. Java相关面试题总结+答案(一)

    [Java基础] 1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,即Java开发工具包,提供了Java 的开发环境和运行环境. JRE:Java Ru ...