编程导航算法通关村第一关|1. 链表基础,链表的创建以及增删改查


编程导航算法通关村第一关|1. 链表基础,链表的创建以及增删改查


1. 什么是链表

链表是一种线性的数据结构,组成链表的基本结构称为节点,每个节点由 ”数据 + 下一节点的指针“ 组成。
![在这里插入图片描述](https://img-blog.csdnimg.cn/c35f14abbf62468c8a2349eea220c1b0.png
在Java中我们是这样去定义一个节点的

public class Node {
//这里将类的参数定义成public只是为了方便访问,
    public int data;
    public Node next;
    public Node() {
    }
    public Node(int data) {
        this.data = data;
    }
}

关于单链表:

  • 不管进行什么操作,一定是从头开始逐个向后访问,所以管理好链表的表头(第一个节点)很重要。

2. 链表的基本操作

为了更好的了解链表,我们从0创建一个链表,并对他进行基本的操作。

 public static void main(String[] args) {

        //测试头插入
        Node head = new Node(2);
        Node node_1 = new Node(1);
        head = insertNode(head, node_1, 1);
        printlnNodeData(head);

        //测试尾插入
        Node node_2 = new Node(4);
        head = insertNode(head, node_2, 3);
        printlnNodeData(head);

        //中间插入
        Node node_3 = new Node(3);
        head = insertNode(head, node_3, 2);
        printlnNodeData(head);

        //中间插入
        Node node_4 = new Node(5);
        head = insertNode(head, node_4, 2);
        printlnNodeData(head);

        //删除头节点
        head = delNode(head, 1);
        printlnNodeData(head);

        //删除尾巴节点
        head = delNode(head, 4);
        printlnNodeData(head);

        //删除中间节点
        head = delNode(head, 2);
        printlnNodeData(head);

    }


    /*
     * 遍历链表,获得链表长度
     * */
    public static int getListLength(Node head){
        int length = 0;
        Node node = head;
        while (node != null){
            length++;
            node = node.next;
        }
        return length;
    }

    /*
     * 遍历输出节点上的数据
     * */
    public static void printlnNodeData(Node head){
        Node node = head;
        while (node != null){
            System.out.print(node.data + "  ");
            node = node.next;
        }
        System.out.println("");
    }

    /*
    * 获得任意位置节点
    * */
    public static Node getNodeByIndex(Node head, int index){
        int size = getListLength(head);
        if (index > size || index < 0){
            throw new IndexOutOfBoundsException("index out!");
        }
        Node temp = head;
        for (int i = 1; i < index; i++) {
            temp = temp.next;
        }
        return temp;
    }


   /*
    * 链表插入节点
    * @author hhy
    * @param head 头节点
    * @param nodeInsert 待插入节点
    * @param index 节点位置,1开始
    * */
    public static Node insertNode(Node head, Node nodeInsert, int index){
        if (head == null) {
            throw new RuntimeException(" headNode is null error !");
        }
        int size = getListLength(head);
        if (index > size + 1 || index < 1){
            throw new IndexOutOfBoundsException("index out!");
        }
        //头插入
        if (index == 1){
            nodeInsert.next = head;
            return nodeInsert;
        }
        //尾巴插入
        /*if (index == size + 1){
            Node last =  getNodeByIndex(head, index - 1);//获取尾节点
            last.next = nodeInsert;
            return head;
        }*/
        //中间插入
        Node last =  getNodeByIndex(head, index - 1);//拿到需要插入的位置的上一个节点
        //这里的操作的顺序不能变
        nodeInsert.next = last.next;
        last.next = nodeInsert;
        return head;
    }

    /*
    * 链表删除节点
     * @author hhy
     * @param head 头节点
     * @param index 节点位置,1开始
    * */
    public static Node delNode(Node head, int index){
        if (head == null) {
            throw new RuntimeException(" headNode is null error !");
        }
        int size = getListLength(head);
        // index这里不像插入的时候可以为 size+1, size+1 上没有节点,删除需要在有节点的情况下才有意义
        if (index > size  || index < 1){
            throw new IndexOutOfBoundsException("index out!");
        }
        //删除头节点
        if (index == 1){
            return head.next;
        }

        //删除尾节点
        if (index == size){
            Node last = getNodeByIndex(head, index - 1);//获取倒数第二个节点
            last.next = null;
            return head;
        }

        //删除中间节点
        Node last = getNodeByIndex(head, index - 1);//获取上一个节点
        last.next = last.next.next;
        return head;
    }

测试结果

1  2  
1  2  4  
1  3  2  4  
1  5  3  2  4  
5  3  2  4  
5  3  2  
5  2  
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值