JAVA基础-链表

链表概念

链表的物理存储结构是非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接的次序实现的.

链表的数据结构

链表由一系列结点组成,每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。链表在插入的时候速度较快,可以达到O(1)的复杂度,但是查找操作较慢,需要O(n)的时间,线性表和顺序表查找操作的时间复杂度分别是O(logn)和O(1)。

代码如下:
public class Node {
    //数据域
    Object value;
    
    Node next;
    public Node(Object value,Node next) {
        this.value=value;
        this.next=next;
    }
    public Object getValue() {
        return value;
    }
    public void setValue(Object value) {
        this.value=value;
    }
    public Node getNext() {
        return next;
    }
    public void setNext(Node next) {
        this.next=next;
    }
  }
public class CLinkedList {
    Node root;
    int size;
    Node last;//表示链表尾节点
}

插入操作:

尾插

    //尾插(不使用last)
    public void add(Object e) {
        if(root==null) {
            root=new Node(e,null);
            size++;
            return;
        }
        Node temp=root;
        while(temp.next!=null) {
            temp=temp.next;
        }
        temp.next=new Node(e,null);
        size++;
    }

头插

    //头插
    public void addFirst(Object e) {
        if(root==null) {
            root=new Node(e,null);
            last = root;
            size++;
            return;
        }
        root=new Node(e,root);
        size++;
    }

利用尾节点last尾插法插入结点

      public void addLast(Object e){
        if(root == null){
          root = new Node (e, null);
          last = root;
          size++;
        }
        last.next = new Node (e, null);
        last = last.next;
        size++;
      }

下标检查

      private boolean checkIndex(int index) {
            if(index<0||index>=size) {
                throw new ArrayIndexOutOfBoundsException("index必须大于0小于"+size);
            }
            return true;
        }

指定位置插入结点

      //在指定位置插入元素
      public void add(int index,Object e){
          Node temp=root;
          checkIndex(index);
          for(int i=0;i<index-1;i++) {
              temp=temp.next;
              }
          Node node=new Node(e,temp.next);
          temp.next=node;
          size++;
          }

在指定结点前添加结点

      //找到e1元素,在e1前插入e2
      public void add(Object e1,Object e2){
          Node temp=root;
          if(temp.value==e1) {
              Node node=new Node(e2,temp);
              root=node;
              size++;
              return;
          }
          while(temp.next!=null) {
              if(temp.next.value==e1) {
                  Node node=new Node(e2,temp.next);
                  temp.next=node;
                  size++;
                  return;
              }
              temp=temp.next;
          }
          System.out.println("找不到"+e1);
         
      }

查找操作:

指定位置查找结点值

      //获取指定位置结点值
      public Object get(int index){
          Node temp=root;
          checkIndex(index);
          //找到索引为index的链表结点
          for(int i=0;i<index;i++) {
              temp=temp.next;
              }
          Object e=temp.value;
          return e;
      }

查找结点所在位置

      //返回索引值
      public int[] get(Object e){
          Node temp=root;
          int index=0;
          int[] getIndex=new int[size];
          for(int i=0;i<size;i++) {
              if(temp.value==e) {
                  getIndex[index++]=i;
              }
              temp=temp.next;
          }
            if (index==0) {
                System.out.println("没有该元素!");
                return new int[] {};
            }
          int[] mannyIndex=new int[index];//定义一个新数组
            mannyIndex=java.util.Arrays.copyOf(getIndex,index);//将原来数组截断,只把下标保存到新数组
            getIndex=null;//将原数组删除
            return mannyIndex;
         }

删除操作:

删除指定位置结点

      public void remove(int index){
          Node temp=root;
          Node pre=temp;
          checkIndex(index);
          //找到索引为index的链表结点

          for(int i=0;i<index;i++) {
              pre=temp;
              temp=temp.next;
             }
          if(temp.next!=null) {
              if(temp==root) {
                  root=root.next;
                  size--;
              }else {
                      pre.next=pre.next.next;
                      size--;
              }
          }else {
              if(temp==root) {
                  root=null;
                  size--;
              }else
              {pre.next=null;
              size--;}
          }
      }

先查找结点比对结点值再删除

      public void removeAll(Object e){
          int[] getIndex=get(e);
          int i=0;
          //找不到
          if(getIndex.length==0) {
              return;
          }
          //
          for(int j=0;j<getIndex.length;j++) {    

              remove(getIndex[j]-i);
              i++;
              }
              
          }

测试:


      public static void main(String[] args){
          CLinkedList clink =new CLinkedList ();
          
          //添加元素
          clink.addFirst(3);
          clink.addFirst(6);
          clink.addFirst(3);
          clink.addFirst(4);
          clink.addFirst(3);
          //在e1前添加e2
          clink.add((Object)6, (Object)4);

          //
//          Object e=3;
//          System.out.print(e+"的索引为");
//          int[] index=clink.get(e);
//          for(int j=0;j<index.length;j++) {              
//              System.out.print(index[j]+" ");
//          }
//          System.out.println();
          //
          clink.removeAll(3);
//          clink.remove(0);
          
          //获取元素
//          System.out.print("当前索引的元素值为:"+ clink.get(1));
          
          
          //打印链表元素和size
          Node temp=clink.root;
          System.out.print("当前链表为");
          while(temp!=null) {
              System.out.print(temp.value+" ");
              temp=temp.next;
          }
          System.out.println();
          System.out.print("当前size为"+clink.size);
      }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值