zoukankan      html  css  js  c++  java
  • (java实现)单链表

    什么是单链表

    在了解单链表之前,你知道什么是链表吗?如果你不知道什么是链表,可以看看我的这篇博客<链表-LinkList>

    单链表是链表的其中一种基本结构。一个最简单的结点结构如图所示,它是构成单链表的基本结点结构。在结点中数据域用来存储数据元素,指针域用于指向下一个具有相同结构的结点。
    因为只有一个指针结点,称为单链表。

    单链表中三个概念需要区分清楚:分别是头指针,头节点和首元节点。

    头结点、头指针和首元结点(此段转自@ciyeer大牛的博客)
    • 头结点:有时,在链表的第一个结点之前会额外增设一个结点,结点的数据域一般不存放数据(有些情况下也可以存放链表的长度等信息),此结点被称为头结点。

    若头结点的指针域为空(NULL),表明链表是空表。头结点对于链表来说,不是必须的,在处理某些问题时,给链表添加头结点会使问题变得简单。
    首元结点:链表中第一个元素所在的结点,它是头结点后边的第一个结点。

    • 头指针:永远指向链表中第一个结点的位置(如果链表有头结点,头指针指向头结点;否则,头指针指向首元结点)。

    • 头结点和头指针的区别:头指针是一个指针,头指针指向链表的头结点或者首元结点;头结点是一个实际存在的结点,它包含有数据域和指针域。两者在程序中的直接体现就是:头指针只声明而没有分配存储空间,头结点进行了声明并分配了一个结点的实际物理内存。

    单链表中可以没有头结点,但是不能没有头指针!
    头节点的引入能使链表对第一个元素的删除和插入和其他元素相同,不用另外说明,使得代码更加简洁。

    单链表的基本操作

    单链表的基本操作有:增(add),删(remove),改(set),查(find),插(insert)等。

    在这里我们只讲解add,remove,insert三个操作,其他实现看源码。

    单链表增添元素
    1. 声明一个新节点node作为新的尾节点,next=null;

    2. 获取原链表的最后一个节点,把它的next指向1步骤的新节点node

    3. 记录链表长度的变量+1

         public void add(AnyType a){
                Node<AnyType> renode=new Node<>(a,null);
                getNode(thesize-1).next=renode;
                thesize++;
            }
    
    单链表删除元素
    1. 获取需要删除的节点的上一个节点node

    2. 把node的next指向node的next的next

    3. 因为node的next节点没有指针指向它,因此它会被系统自动清理

    4. 记录链表长度的变量-1

         public AnyType remove(int i){
            Node<AnyType> prev=getNode(i-1);
            AnyType a=prev.next.data;
            prev.next=prev.next.next;
            thesize--;
            return  a;
        }
    
    单链表插入元素
    1. 获取需要插入的位置的节点;

    2. 声明一个新节点node指向1步骤得到的节点;

    3. 获取需要插入位置节点的上一个节点;

    4. 将3步骤得到的节点的next指向新节点node;

    5. 记录链表长度的变量+1。

         public void insert(int i,AnyType a){
                Node<AnyType> prev=getNode(i-1);
                Node<AnyType> renode=new Node<>(a,prev.next);
                prev.next=renode;
                thesize++;
         }
    

    源码实现(java)

    /*
    结点
     */
    public class Node<AnyType> {
        public  AnyType data;
        public  Node<AnyType> next;
        public Node(AnyType data,Node<AnyType> next){
            this.data=data;
            this.next=next;
        }
    }
    
    -----
    public class MyLinkList<AnyType> {
    
        //首元节点
        private Node<AnyType> first;
    
        //头指针
        private Node<AnyType> head;
    
        //链表长度
        int thesize;
    
        //初始化链表
        public boolean initlist(){
            thesize=0;
            first=new Node<>(null,null);
            head=new Node<>(null,first);
            return true;
        }
    
        //判断链表是否为空
        public boolean isEmpty(){
            return thesize==0;
        }
    
        //获取节点
        public Node<AnyType> getNode(int i){
            Node<AnyType> renode=head;
            for(int j=-2;j<i;j++){
                renode=renode.next;
            }
            return renode;
        }
    
        //在末尾添加元素
        public void add(AnyType a){
            Node<AnyType> renode=new Node<>(a,null);
            getNode(thesize-1).next=renode;
            thesize++;
        }
    
        //删除i位置节点,并返回删掉的数据
        public AnyType remove(int i){
            if(i==thesize-1){
                AnyType a=getNode(thesize-1).data;
                getNode(thesize-2).next=null;
                return a;
            }
            Node<AnyType> prev=getNode(i-1);
            AnyType a=prev.next.data;
            prev.next=prev.next.next;
            thesize--;
            return  a;
        }
    
        //在i位置插入新节点
        public void insert(int i,AnyType a){
            Node<AnyType> prev=getNode(i-1);
            Node<AnyType> renode=new Node<>(a,prev.next);
            prev.next=renode;
            thesize++;
        }
    
        //获取i位置节点的数据
        public AnyType get(int i){
            return getNode(i).data;
        }
    
        //为i位置元素重新赋值
        public void set(int i,AnyType a){
            getNode(i).data=a;
        }
    
        //返回链表节点个数
        public int length(){
            return thesize;
        }
    
        //清空链表
        public void clear(){
            initlist();
        }
    
        //打印链表
        public void print(){
            for(int i=0;i<thesize;i++){
                System.out.println(getNode(i).data);
            }
        }
    
    }
    
    
    花五年时间成为某个领域的专家
  • 相关阅读:
    《几何与代数导引》例2.7.2
    《几何与代数导引》例2.6
    《几何与代数导引》习题1.37.3
    《几何与代数导引》习题1.37.3
    《几何与代数导引》例2.7.1
    《几何与代数导引》例2.7.1
    《几何与代数导引》例2.7.2
    《几何与代数导引》习题1.38
    《几何与代数导引》例2.6
    Android ApiDemo 笔记(一)Content与Graphics
  • 原文地址:https://www.cnblogs.com/sang-bit/p/11609824.html
Copyright © 2011-2022 走看看