当前位置:   article > 正文

Java数据结构---链表的基本用法(如创建等基本使用方法)_java 怎么使用链表

java 怎么使用链表

目录

一、单链表

(1)addFirst

(2)addLast

(3)遍历

(4)get

(5)insert

(6)removeFirst

(7)remove

二、双向链表

(1)insert

(2)remove

(3)addLast

(4) removeLast

三、双向环形链表

(1)添加

(2)删除首部和尾部

(3)删除或者寻找对应值的节点


一、单链表

  1. //单向链表类
  2. public class LinkedList {
  3. //头指针
  4. private Node head=null;
  5. private static class Node{
  6. int value;
  7. Node next;
  8. public Node(int value,Node next){
  9. this.value=value;
  10. this.next=next;
  11. }
  12. }
  13. }

(1)addFirst

  1. //头部添加元素
  2. public void addFirst(int value){
  3. head=new Node(value,head);
  4. }

(2)addLast

  1. //找到链表中的最后一个节点
  2. public Node findLast(){
  3. if(head==null){
  4. return null;
  5. //空链表
  6. }
  7. Node p;
  8. for(p=head;p.next!=null;p=p.next){
  9. }
  10. return p;
  11. }
  12. //向链表尾部添加元素
  13. public void addLast(int value){
  14. Node last=findLast();
  15. if(last==null){
  16. addFirst(value);
  17. return;
  18. }
  19. last.next=new Node(value,null);
  20. }

(3)遍历

  1. //遍历链表
  2. public void loop(){
  3. Node p=head;
  4. while(p!=null){
  5. System.out.print(p.value+" ");
  6. p=p.next;
  7. }
  8. System.out.println();
  9. }

(4)get

获取指定索引的节点的value值。

这里注意一下findNode方法是获取指定索引处的节点,所以需要一个计量器i,让这个i=0开始,为什么呢?因为head其实就是第一个节点,后面双向链表计量i是=-1开始的,但是双向链表中的head并不是第一个节点,它的next才是第一个节点,所以一定要特别注意单向链表中的head与双向链表的head的区别(个人看法)

  1. //找到指定索引处的节点
  2. public Node findNode(int index){
  3. int i=0;
  4. for(Node p=head;p.next!=null;p=p.next,i++){
  5. if(i==index){
  6. return p;
  7. }
  8. }
  9. return null;//没有找到该节点
  10. }
  11. //获取指定索引处的节点的值(value)
  12. public int get(int index){
  13. Node p=findNode(index);
  14. if(p==null){
  15. throw new IllegalArgumentException(String.format("index[%d]不合法",index));
  16. }
  17. return p.value;
  18. }

(5)insert

  1. //向索引位置插入
  2. public void insert(int index,int value){
  3. if(index==0){
  4. addFirst(value);
  5. }
  6. //找到上一个节点
  7. Node prev=findNode(index-1);
  8. if(prev==null){
  9. throw new IllegalArgumentException(String.format("index[$d]不合法",index));
  10. }
  11. prev.next=new Node(value,prev.next);
  12. }

(6)removeFirst

  1. //删除第一个节点
  2. public void removeFirst(){
  3. if(head==null){
  4. throw new IllegalArgumentException(String.format("index[0]不合法"));
  5. }
  6. head=head.next;
  7. }

(7)remove

  1. //删除指定索引处的节点
  2. public void remove(int index){
  3. if(index==0){
  4. removeFirst();
  5. return;
  6. }
  7. Node prev=findNode(index-1);//上一个节点
  8. if(prev==null){
  9. throw new IllegalArgumentException(String.format("索引异常"));
  10. }
  11. Node removed=prev.next;//被删除的节点
  12. if(removed==null){
  13. throw new IllegalArgumentException(String.format("索引异常"));
  14. }
  15. prev.next=removed.next;
  16. }

二、双向链表

  1. //双向链表类
  2. public class DoubleLinkedList {
  3. private Node head;
  4. private Node tail;
  5. private static class Node{
  6. Node prev;
  7. int value;
  8. Node next;
  9. public Node(Node prev,int value,Node next){
  10. this.prev=prev;
  11. this.value=value;
  12. this.next=next;
  13. }
  14. }
  15. //初始化
  16. public DoubleLinkedList(){
  17. head=new Node(null,100,null);
  18. tail=new Node(null,999,null);
  19. head.next=tail;
  20. tail.prev=head;
  21. }
  22. }

(1)insert

在指定索引处添加

  1. //找到指定索引处的节点
  2. private Node findNode(int index){
  3. int i=-1;
  4. for(Node p=head;p!=tail;i++,p=p.next){
  5. if(i==index){
  6. return p;
  7. }
  8. }
  9. return null;
  10. }
  11. //向指定位置添加节点
  12. public void insert(int index,int value){
  13. Node prev=findNode(index-1);
  14. if(prev==null){
  15. throw new IllegalArgumentException(String.format("索引异常"));
  16. }
  17. Node next=prev.next;
  18. Node inserted=new Node(prev,value,next);
  19. prev.next=inserted;
  20. next.prev=inserted;
  21. }

(2)remove

删除指定索引处的节点

  1. //删除指定索引处的节点
  2. public void remove(int index){
  3. Node prev=findNode(index-1);
  4. if(prev==null){
  5. throw new IllegalArgumentException(String.format("索引异常"));
  6. }
  7. Node removed=prev.next;
  8. //如果删除的元素是尾哨兵
  9. if(removed==tail){
  10. throw new IllegalArgumentException(String.format("索引异常"));
  11. }
  12. Node next=removed.next;
  13. prev.next=next;
  14. next.prev=prev;
  15. }

(3)addLast

 向尾部添加节点

  1. //向尾部添加元素
  2. public void addLast(int value){
  3. Node last=tail.prev;
  4. Node added=new Node(last,value,tail);
  5. last.next=added;
  6. tail.prev=added;
  7. }

(4) removeLast

  1. //删除最后一个节点
  2. public void removeLast(){
  3. Node removed=tail.prev;
  4. if(removed==head){
  5. throw new IllegalArgumentException(String.format("索引异常"));
  6. }
  7. Node prev=removed.prev;
  8. prev.next=tail;
  9. tail.prev=prev;
  10. }

三、双向环形链表

 双向环形链表(我这里说的是有哨兵节点的)不同的地方在于,尾结点的next指向了哨兵节点,哨兵节点的next指向的是第一个节点,哨兵节点的prev指向的是尾节点。

  1. //双向环形链表
  2. //注意是有哨兵节点sentinel
  3. //sentinel.next是第一个节点,sentinel.prev是最后一个节点
  4. public class DoubleSentinelList {
  5. private static class Node{
  6. Node prev;
  7. int value;
  8. Node next;
  9. public Node(Node prev, int value, Node next) {
  10. this.prev = prev;
  11. this.value = value;
  12. this.next = next;
  13. }
  14. }
  15. private Node sentinel=new Node(null,-1,null);//哨兵节点
  16. //初始化
  17. public DoubleSentinelList(){
  18. sentinel.next=sentinel;
  19. sentinel.prev=sentinel;
  20. }
  21. }

(1)添加

  1. //向首部添加
  2. public void addFirst(int value){
  3. Node a=sentinel;
  4. Node b=sentinel.next;
  5. Node added=new Node(a,value,b);
  6. a.next=added;
  7. b.prev=added;
  8. }
  9. //向尾部添加
  10. public void addLast(int value){
  11. Node a=sentinel.prev;
  12. Node b=sentinel;
  13. Node added=new Node(a,value,b);
  14. a.next=added;
  15. b.prev=added;
  16. }

(2)删除首部和尾部

  1. //删除首部
  2. public void removeFirst(){
  3. Node removed=sentinel.next;
  4. if(removed==sentinel){
  5. throw new IllegalArgumentException(String.format("非法"));
  6. }
  7. Node a=sentinel;
  8. Node b=removed.next;
  9. a.next=b;
  10. b.prev=a;
  11. }
  12. //删除尾部
  13. public void removeLast(){
  14. Node removed=sentinel.prev;
  15. if(removed==sentinel){
  16. throw new IllegalArgumentException(String.format("非法"));
  17. }
  18. Node a=removed.prev;
  19. Node b=sentinel;
  20. a.next=b;
  21. b.prev=a;
  22. }

(3)删除或者寻找对应值的节点

  1. //根据值寻找对应的节点
  2. public Node findByValue(int value){
  3. Node p=sentinel.next;
  4. while(p!=sentinel){
  5. if(p.value==value){
  6. return p;
  7. }
  8. p=p.next;
  9. }
  10. return null;
  11. }
  12. //根据值删除对应的节点
  13. public void removeByValue(int value){
  14. Node removed=findByValue(value);
  15. if(removed==null){
  16. return;//不用删除,因为没找到
  17. }
  18. Node a=removed.prev;
  19. Node b=removed.next;
  20. a.next=b;
  21. b.prev=a;
  22. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/823024
推荐阅读
相关标签
  

闽ICP备14008679号