List.java(接口)

public interface List<T> {void addHead(T value);void addTail(T value);void removeHead();void removeTail();void removeValue(T value);void change(T srcValue,T aimValue);boolean search(T value);int size();}

单链表的基本操作

SingleLink实现List接口,实现头增,头删,尾增,尾删,替换,删除特定元素等方法


public class SingleLink<E extends Comparable<E>> implements List<E> {//单链表private Node<E> head;//头private Node<E> tail;//尾int size;//统计节点个数@Overridepublic void addHead(E value) {//在头部添加一个节点Node<E> newNode = new Node<E>(value);//申请节点if (head == null) {//链表里没有任何元素head = newNode;tail = newNode; //将尾部也更新到新节点中} else {newNode.next = head;//新的节点的下一个保存原来的头结点head = newNode;//更新头结点}size++;}@Overridepublic void addTail(E value) {//在尾部添加一个节点Node<E> newNode = new Node<E>(value);if (size == 0) {//链表里没有任何元素     //if(head == null)head = newNode;tail = newNode; //将尾部也更新到新节点中} else {tail.next = newNode;//尾巴节点的下一个保存新节点tail = newNode;//更新尾结点}size++;}@Overridepublic void removeHead() {//删除头结点if (size == 0) {return;}head.value = null;//释放空间if (size == 1) {//链表只有一个节点时,头部和尾部都为nullhead = null;tail = null;} else {head = head.next;//头部指向头部的下一个}size--;}@Overridepublic void removeTail() {//删除尾节点Node<E> p = head;if (size == 0) {return;}tail.value = null;//释放空间if (size == 1) {//链表只有一个节点时,头部和尾部都为nullhead = null;tail = null;} else {for (; p.next != tail; p = p.next) {}p.next = null;//尾巴的next =nulltail = p;//更新尾巴}size--;}@Overridepublic void removeValue(E value) {//删除指定元素(可能有多个节点的value值是该元素)if (size == 0) {return;}if (tail.value.compareTo(value) == 0) {//如果尾结点等于指定节点,调用删除尾结点方法removeTail();removeValue(value);}if (head.value.compareTo(value) == 0) {如果头结点等于指定节点,调用删除尾结点方法removeHead();removeValue(value);} else if (size == 1 && head.value.compareTo(value) != 0) {return;} else { //size>=2   head.value != valuefor (Node<E> p = head; p.next != null; ) {if (p.next.value.compareTo(value) == 0) {
//                    if(p.next == tail){
//                        tail = p;
//                    }p.next.value = null;// 防止内存泄漏p.next = p.next.next;size--;} else {p = p.next;}}}}@Overridepublic void change(E srcValue, E aimValue) {//改变节点的value值for (Node<E> p = head; p != null; p = p.next) {if (p.value.compareTo(srcValue) == 0) {//遍历链表找到要替换的节点,重新把新的值赋值给valuep.value = aimValue;}}}public Node<E> getHead() {return head;}public Node<E> getTail() {return tail;}public void setHead(Node<E> head) {this.head = head;}public void setTail(Node<E> tail) {this.tail = tail;}@Overridepublic boolean search(E value) {//判断元素是否存在for (Node<E> p = head; p != null; p = p.next) {if (p.value.compareTo(value) == 0) {return true;}}return false;}@Overridepublic int size() {return size;}//返回size元素个数public void show() {//展示链表中所有的元素for (Node<E> p = head; p != null; p = p.next) {System.out.print(p.value + "\t");}System.out.println();}static class Node<T> {private T value;private Node<T> next;public T getValue() {return value;}public Node<T> getNext() {return next;}public void setNext(Node<T> next) {this.next = next;}public Node(T value) {this.value = value;}}}

测试代码:

 public static <T> void main(String[] args) {SingleLink<Integer> singleLink = new SingleLink<>();//头插System.out.println("头插3:");singleLink.addHead(3);//3singleLink.show();//头插System.out.println("头插2:");singleLink.addHead(2); // 2 3singleLink.show();//头插System.out.println("头插2:");singleLink.addHead(2);//2 2 3singleLink.show();//尾插System.out.println("尾插4:");singleLink.addTail(4);// 2 2 3 4singleLink.show();//尾插System.out.println("尾插2:");singleLink.addTail(2);//2 2 3 4 2singleLink.show();//头插System.out.println("头插4:");singleLink.addHead(4);// 4 2 2 3 4 2singleLink.show();//删除指定元素System.out.println("删除2:");singleLink.removeValue(2);//4    3   4singleLink.show();//修改元素 4->6System.out.println("修改4为6:");singleLink.change(4,6);singleLink.show();//查找4这个元素是否存在System.out.println("元素4是否存在:"+singleLink.search(4));//删除尾部System.out.println("尾删:");singleLink.removeTail(); //4 3singleLink.show();//删除头部System.out.println("头删:");singleLink.removeHead();//3singleLink.show();
}

运行结果:

单链表的其他操作:

链表倒置,判断有无环,合并有序链表,寻找相交节点

  //单链表逆置问题public SingleLink<E> reverse() {if (head == null || size == 1) {//如果没有节点或者为1,返回这个链表return this;}Node<E> p = head, q = p.next, s = p.next.next;head.next = null;//原来的头 ->逆至尾巴(tail = null)
//        while(p.next== null){while (q != null) {q.next = p;p = q;q = s;if (s != null) {s = s.next;}}//原链表的头->尾巴,原来尾巴 ->现在头tail = head;head = p;//p指向的是现在链表的尾部return this;}//判断链表是否有环  快慢引用  定义一个fast和slow指针,fast = fast.next.next; solw = solw.next;public boolean isLoop() {Node<E> node = isLoop0();if (node == null) {return false;} else {return true;}}public Node<E> isLoop0() {Node<E> fast = head, slow = head;do {if (fast.next == null || fast == null) {return null;}fast = fast.next.next;slow = slow.next;} while (fast != slow);return fast;}//输出环的入口点public Node<E> getEntranceNode() {Node<E> node = isLoop0();boolean result = isLoop();if (result == false) {return null;}//node位置 相遇点Node<E> p = head, q = node;while (p != q) {p = p.next;q = q.next;}return p;}//两个链表相交 找出相交节点public Node<E> intersectNode(SingleLink<E> link) {if (link == null) {return null;}Node<E> long_node = size > link.size ? this.head : link.head;//长链表Node<E> short_node = size < link.size ? this.head : link.head;//短链表//长链表先走差值步int difference = Math.abs(size - link.size);while (difference > 0) {long_node = long_node.next;difference--;}//长短链表一起遍历while (short_node != long_node) {long_node = long_node.next;short_node = short_node.next;}return short_node;}//两个有序链表合并成一个有序链表public static <T extends Comparable<T>> Node<T> mergeTwoLink(SingleLink<T> link1, SingleLink<T> link2) {if (link1 == null) {return link2.head;}if (link1 == null) {return link1.head;}//找新头结点  看两个链表的头哪个比较小Node<T> newHead = link1.head.value.compareTo(link2.head.value) > 0 ? link2.head : link1.head;Node<T> newTail = newHead;Node<T> p = newHead.next;//p遍历头节点比较小的链表Node<T> q = newHead == link1.head ? link2.head : link1.head;//while (p != null && q != null) {if (p.value.compareTo(q.value) > 0) {newTail.next = q;newTail = q;q = q.next;} else {newTail.next = p;newTail = p;p = p.next;}}//如果link2先走完,p遍历完成   若link1先走完,q遍历完成if (p == null) {newTail.next = q;newTail = q;} else {newTail.next = p;newTail = p;}return newHead;}

测试代码:

 public static <T> void main(String[] args) {// 翻转链表SingleLink<Integer> singleLink1 = new SingleLink<>();singleLink1.addHead(9);singleLink1.addHead(5);singleLink1.addHead(3);singleLink1.addHead(1);singleLink1.reverse();System.out.println("singleLink1倒置:");singleLink1.show();System.out.println();//判断是否有环singleLink1.getTail().setNext(singleLink1.getHead());//添加环System.out.println("singleLink1是否有环:"+singleLink1.isLoop());//打印是否有环System.out.println("singleLink1有环的节点:"+singleLink1.getEntranceNode().getValue());System.out.println();
//        两个有序链表合并SingleLink<Integer> singleLink2 = new SingleLink<>();singleLink2.addHead(9);singleLink2.addHead(5);singleLink2.addHead(3);singleLink2.addHead(1);SingleLink<Integer> singleLink3 = new SingleLink<>();singleLink3.addHead(6);singleLink3.addHead(4);singleLink3.addHead(2);// 2 4 6SingleLink.Node<Integer> newHead = singleLink3.mergeTwoLink(singleLink2, singleLink3);//输出新链表的第一个节点元素System.out.println("新有序链表的第一个元素:"+newHead.getValue());//遍历新的有序链表System.out.println("有序链表为:");for ( SingleLink.Node<Integer>p = newHead; p!= null; p = p.getNext()) {System.out.print(p.getValue() + "\t");}System.out.println();
}

运行结果:

java-基本数据结构-单链表相关推荐

  1. 【Java】数据结构—— 单链表和双链表

    文章目录 一.单链表 前期准备: 1.添加结点 2.遍历链表 3.修改结点 4.删除结点 5.获取长度 6.获取链表的倒数第N个结点 7.反转链表 8.反转打印链表 9.按照编号有序添加结点 10.在 ...

  2. 20175330 数据结构-单链表(选做)

    要求 参见附件,补充MyList.java的内容,提交运行结果截图(全屏) 课下推送代码到码云 ``` public class MyList {     public static void mai ...

  3. php链表和联表的区别,PHP_浅谈PHP链表数据结构(单链表),链表:是一个有序的列表,但 - phpStudy...

    浅谈PHP链表数据结构(单链表) 链表:是一个有序的列表,但是它在内存中是分散存储的,使用链表可以解决类似约瑟夫问题,排序问题,搜索问题,广义表 单向链表,双向链表,环形链表 PHP的底层是C,当一个 ...

  4. php mysql 链表_浅谈PHP链表数据结构(单链表)

    链表:是一个有序的列表,但是它在内存中是分散存储的,使用链表可以解决类似约瑟夫问题,排序问题,搜索问题,广义表 单向链表,双向链表,环形链表 PHP的底层是C,当一个程序运行时,内存分成五个区(堆区, ...

  5. java语言实现单链表---不含头结点

    java语言实现单链表---不含头结点 一.相关概念 1.什么是线性表 2.什么是顺序表 3.什么是链表 4.单链表.双链表.循环单链表.循环双链表 5.头结点和首结点 6.常见的栈和队列与线性表的关 ...

  6. 数据结构——单链表的C++实现

    数据结构--单链表的C++实现 \qquad单链表的创建.求长度.查找.插入和删除的C++实现. #include<iostream> using namespace std;//1.定义 ...

  7. python 单链表是否有回路_(Python3)数据结构--单链表之判断链表是否有环

    前言 有Python基础 有数据结构单链表基础,没接触过的可以看下面链接 https://blog.csdn.net/sf9898/article/details/104946291 原理和实现 有一 ...

  8. 数据结构 —— 单链表(超详细图解 接口函数实现)

    系列文章目录 数据结构 -- 顺序表 数据结构 -- 单链表 数据结构 -- 双向链表 数据结构 -- 队列 数据结构 -- 栈 数据结构 -- 堆 数据结构 -- 二叉树 数据结构 -- 八大排序 ...

  9. C语言数据结构单链表链表

    数据结构–单链表 学习了顺序表,我们发现顺序表在向里面存放数据的时候很麻烦,比如我们要使用头插法存放一个数据到顺序表的时候,我们要将整个表都向后挪一位,这个操作就让人很难受.那么有没有一种结构可以让我 ...

  10. 数据结构——单链表(小白入门第二天)

    一.什么是单链表? 定义:每个结点 除了存放数据元素外,还要存储指向下一个节点的指针: 优点:不要求大片连续空间,改变容量方便: 缺点:不可随机存取,要耗费一定空间存放指针 局限性:无法逆向检索 二. ...

最新文章

  1. ConnectionAbortedError: [WinError 10053] 您的主机中的软件中止了一个已建立的连接
  2. 实验吧_NSCTF web200FALSE(代码审计)
  3. java semaphore 等待_Java并发编程系列之Semaphore详解
  4. java堆栈_java线程的堆栈跟踪之jstack篇
  5. 华硕 tuf b360 efi_技嘉小雕、微星迫击炮、华硕电竞特工三款主板对比
  6. FlinkSQL建表语句与插入语句
  7. c语言标准库函数fputs,C 库函数
  8. 教你怎么录制电脑内部发出的声音
  9. python计算圆环的面积_圆环的面积计算公式
  10. 2022-2028年中国铝合金行业市场运营格局及前景战略分析报告
  11. 牛逼,一个开源,高隐私,自架自用的聚合搜索引擎
  12. 毕设 JAVA超市管理系统论文
  13. RCF—用于C++的进程间通讯(1)
  14. python:考试前,练手习题(斐波那契数,字符串排序,九九乘法表,水仙花数,求和...求数字倍数,(保佑不挂科!)
  15. 智能红外遥控器(五):手机蓝牙控制格力空调
  16. 全像素双核激光对焦拍照是个什么厉害玩意儿
  17. Hypervisor介绍(二)
  18. Tomcat部署war程序
  19. 一名开源拓荒者的 Apache 之旅
  20. 如何用Zabbix监控OpenWrt路由器-Zabbix-Agent安装篇

热门文章

  1. HTTP长连接、短连接使用及测试
  2. vert.x web模块(七)
  3. 班农注定落得如此下场
  4. 線上 Android/Linux Kernel Source Code瀏覽 - Android/Linux Source Code Cross Reference
  5. 这次的室温超导爆炸性发现,会是人类的进步?
  6. 鞭炮游戏 甲、乙,丙三人同时开始放第一个鞭炮
  7. 拼多多店群玩法赚钱吗?精细化玩法怎么操作
  8. 【Flutter】利用nfc_manager 读取NFC交通卡信息
  9. 电脑上的计算机怎么移动硬盘,苹果笔记本移动硬盘如何使用_怎样在苹果电脑上用移动硬盘-win7之家...
  10. sin傅里叶变换公式_全面解析傅立叶变换(非常详细)