栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

链表(图解)及简单实现(Java)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

链表(图解)及简单实现(Java)

一、链表的概念

链表是是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
链表分为单链表、双链表、循环链表

二、链表的实现(以单链表为例)
1.单链表         1.)什么是单链表:

单向链表是一种线性表,实际上是由节点(Node)组成的,一个链表拥有不定数量的节点。其数据在内存中存储是不连续的,它存储的数据分散在内存中,每个节点只能也只有它能知道下一个节点的存储位置。由N各节点(Node)组成单向链表,每一个Node记录本Node的数据及下一个Node。向外暴露的只有一个头结点(Head),我们对链表的所有操作,都是直接或者间接地通过其头结点来进行的。

        2.)单链表的图解

2.单链表的代码实现
 1).单链表及结点的定义
class SingleList{

    Node head;//定义一个头节点,头节点不动,不存放具体的值
    private int Length;//链表的长度

    public  SingleList(){
        head=null;
        Length = 0 ;
    }

    //返回链表的长度
    public int length(){
        return this.Length;
    }
    
    //判断所需要操作位置的节点是否存在
    private void outLength(int index){
        if(this.Length < index || index < 0 ){ //需要操作位置大于链表长度,则抛出错误
            throw new IndexOutOfBoundsException();
        }
    }
    
}

//定义一个Node,每个Node就是一个节点
class Node {
    private int data;
    public Node next;

    public Node(int data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Node{" +
                " data='" + data + ''' +
                '}';
    }
}
2).链表的增删改查实现 

增加节点:a.增加头节点 ;b.在指定索引处增加节点;c.在链表尾部增加节点

    
    public void addHead(Node node){
        //因为Head 为 null 所有直接将 head 给 node 的指向就行
        node.next = this.head;
        this.head = node;
        this.Length++;
    }

    
    public void add(int index ,Node node ){
        outLength(index);//需要操作位置大于链表长度,则抛出错误

        if(index == 0 ){ //若要添加位置再头节点,直接调用add(方法)
            addHead(node);
            return;
        }

        Node temp = head; // 辅助链表
        while (index >1 ){
            temp = temp.next; //指向下一个节点
            index --;
        }
        node.next = temp.next;//当前 节点 指向的 下一个节点 指向 Node 的下一个的节点
        temp.next = node ;
        this.Length++; //链表长度加1
    }

    
    public void addList(Node node){
        add(Length,node ); //index 为链表的长度
    }

删除节点:a.删除头节点;b.删除指定索引位置的节点;c.删除尾部节点

    
    public Node removeHead(){
        //判断链表是否为空
        if(Length == 0){
            return null ;
        }
        //定义一个Node 接收原先的头节点
        Node node = head ;
        head = head.next ; //然后删掉原头节点
        node.next =null; //将原先头节点的指向改成 null
        this.Length--;
        return node;
    }

    
    public Node remove(int index){
        outLength(index-1);//需要操作位置大于链表长度,则抛出错误

        boolean flag = true;
        Node temp = head; // 辅助链表
        Node node = null;
        while (flag){
            if(index-1 < 1 ){
                flag = false ;
                break;
            }
            temp = temp.next; //指向下一个节点
            index --;
        }
        node = temp.next; //储存要删除的节点,便于返回
        temp.next = temp.next.next;
        node.next = null;
        this.Length--; //链表长度减1
        return node;
    }

    
    public Node removeList(){
        Node node = remove(this.Length-1);
        this.Length--;
        return node;
    }

查询指定节点

    
    public Node showNode(int index){
        outLength(index);

        boolean flag = true;
        Node temp = head; // 辅助链表

        //将指针指向指定节点
        while (flag){
            if(index < 1 ){
                flag = false ;
                break;
            }
            temp = temp.next; //指向下一个节点
            index --;
        }

        return temp;
    }

    
    public void showList(){
        if(head == null){
            System.out.println("此链表为空");
        }
        Node temp = head ;
        while (temp != null){
            System.out.println(temp);
            temp=temp.next; //指向下一个节点
        }
    }

修改指定节点

    
    public Node upData(int index , Node upNode){
        outLength(index);

        boolean flag = true;
        Node temp = head; // 辅助链表
        Node node = null;

        //将指针指向指定节点的前一位
        while (index == 1 ){
            temp = temp.next; //指向下一个节点
            index --;
        }

        node = temp; // 用来储存修改前的节点
        upNode.next = temp.next.next; //将修改后节点 指向 修改前 下一个节点
        temp.next = upNode; //修改节点信息
        node.next = null; // 将前节点的指向改为 null

        return node;
    }
}

3.)测试代码
    public static void main(String[] args) {
        SingleList sl1 = new SingleList();

        Node n1 = new Node(1);
        Node n2 = new Node(2);
        Node n3 = new Node(3);
        Node n4 = new Node(4);
        Node n5 = new Node(5);

        //插入头节点
        sl1.addHead(n1);
        sl1.addHead(n2);
        //打印全部节点
        sl1.showList();
        System.out.println("--------");

        //插入头节点
        sl1.addHead(n3);
        //打印全部节点
        sl1.showList();
        System.out.println("--------");

        //插入链表尾部
        sl1.addList(n4);
        //打印全部节点
        sl1.showList();
        System.out.println("--------");

        //指定索引处加入节点
        sl1.add(2,n5);
        //打印全部节点
        sl1.showList();
        System.out.println("此时链表长度为:"+ sl1.length());
        System.out.println("--------");

        //删除头节点
        sl1.removeHead();
        //打印全部节点
        sl1.showList();
        System.out.println("--------");

        //删除尾部节点
        sl1.removeList();
        //打印全部节点
        sl1.showList();
        System.out.println("--------");

        //删除指定位置节点
        sl1.remove(1);
        //打印全部节点
        sl1.showList();
        System.out.println("此时链表长度为:"+ sl1.length());
        System.out.println("--------");

        //修改节点
        sl1.upData(0,new Node (8));
        //打印全部节点
        sl1.showList();
        System.out.println("此时链表长度为:"+ sl1.length());
        System.out.println("--------");

        //查询指定节点
        System.out.println(sl1.showNode(0));

    }
}
完整代码
public class SingleListDome {

    public static void main(String[] args) {
        SingleList sl1 = new SingleList();

        Node n1 = new Node(1);
        Node n2 = new Node(2);
        Node n3 = new Node(3);
        Node n4 = new Node(4);
        Node n5 = new Node(5);

        //插入头节点
        sl1.addHead(n1);
        sl1.addHead(n2);
        //打印全部节点
        sl1.showList();
        System.out.println("--------");

        //插入头节点
        sl1.addHead(n3);
        //打印全部节点
        sl1.showList();
        System.out.println("--------");

        //插入链表尾部
        sl1.addList(n4);
        //打印全部节点
        sl1.showList();
        System.out.println("--------");

        //指定索引处加入节点
        sl1.add(2,n5);
        //打印全部节点
        sl1.showList();
        System.out.println("此时链表长度为:"+ sl1.length());
        System.out.println("--------");

        //删除头节点
        sl1.removeHead();
        //打印全部节点
        sl1.showList();
        System.out.println("--------");

        //删除尾部节点
        sl1.removeList();
        //打印全部节点
        sl1.showList();
        System.out.println("--------");

        //删除指定位置节点
        sl1.remove(1);
        //打印全部节点
        sl1.showList();
        System.out.println("此时链表长度为:"+ sl1.length());
        System.out.println("--------");

        //修改节点
        sl1.upData(0,new Node (8));
        //打印全部节点
        sl1.showList();
        System.out.println("此时链表长度为:"+ sl1.length());
        System.out.println("--------");

        //查询指定节点
        System.out.println(sl1.showNode(0));

    }
}

class SingleList{

    Node head;//定义一个头节点,头节点不动,不存放具体的值
    private int Length;//链表的长度

    public  SingleList(){
        head=null;
        Length = 0 ;
    }

    
    public static Node reverseIteratively(Node head){
        Node next = null;
        Node temp = head;  // 辅助节点
        Node reverse = null;//用来储存逆转后的链表

        while(temp == null){
        }

        return null;
    }

    //返回链表的长度
    public int length(){
        return this.Length;
    }

    //判断所需要操作位置的节点是否存在
    private void outLength(int index){
        if(this.Length < index || index < 0 ){ //需要操作位置大于链表长度,则抛出错误
            throw new IndexOutOfBoundsException();
        }
    }


    
    public void addHead(Node node){
        //因为Head 为 null 所有直接将 head 给 node 的指向就行
        node.next = this.head;
        this.head = node;
        this.Length++;
    }

    
    public void add(int index ,Node node ){
        outLength(index);//需要操作位置大于链表长度,则抛出错误

        if(index == 0 ){ //若要添加位置再头节点,直接调用add(方法)
            addHead(node);
            return;
        }

        Node temp = head; // 辅助链表
        while (index >1 ){
            temp = temp.next; //指向下一个节点
            index --;
        }
        node.next = temp.next;//当前 节点 指向的 下一个节点 指向 Node 的下一个的节点
        temp.next = node ;
        this.Length++; //链表长度加1
    }

    
    public void addList(Node node){
        add(Length,node ); //index 为链表的长度
    }

    
    public Node removeHead(){
        //判断链表是否为空
        if(Length == 0){
            return null ;
        }
        //定义一个Node 接收原先的头节点
        Node node = head ;
        head = head.next ; //然后删掉原头节点
        node.next =null; //将原先头节点的指向改成 null
        this.Length--;
        return node;
    }

    
    public Node remove(int index){
        outLength(index-1);//需要操作位置大于链表长度,则抛出错误

        boolean flag = true;
        Node temp = head; // 辅助链表
        Node node = null;
        while (flag){
            if(index-1 < 1 ){
                flag = false ;
                break;
            }
            temp = temp.next; //指向下一个节点
            index --;
        }
        node = temp.next; //储存要删除的节点,便于返回
        temp.next = temp.next.next;
        node.next = null;
        this.Length--; //链表长度减1
        return node;
    }

    
    public Node removeList(){
        Node node = remove(this.Length-1);
        this.Length--;
        return node;
    }

    
    public Node showNode(int index){
        outLength(index);

        boolean flag = true;
        Node temp = head; // 辅助链表

        //将指针指向指定节点
        while (flag){
            if(index < 1 ){
                flag = false ;
                break;
            }
            temp = temp.next; //指向下一个节点
            index --;
        }

        return temp;
    }

    
    public void showList(){
        if(head == null){
            System.out.println("此链表为空");
        }
        Node temp = head ;
        while (temp != null){
            System.out.println(temp);
            temp=temp.next; //指向下一个节点
        }
    }

    
    public Node upData(int index , Node upNode){
        outLength(index);

        boolean flag = true;
        Node temp = head; // 辅助链表
        Node node = null;

        //将指针指向指定节点的前一位
        while (index == 1 ){
            temp = temp.next; //指向下一个节点
            index --;
        }

        node = temp; // 用来储存修改前的节点
        upNode.next = temp.next.next; //将修改后节点 指向 修改前 下一个节点
        temp.next = upNode; //修改节点信息
        node.next = null; // 将前节点的指向改为 null

        return node;
    }
}

//定义一个Node,每个Node就是一个节点
class Node {
    private int data;
    public Node next;

    public Node(int data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Node{" +
                " data='" + data + ''' +
                '}';
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/842929.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号