《大话数据结构》----线性表-----链式存储结构(单链表)实现-- java实现

大话数据结构----线性表单链表存储结构-- java简单实现笔记

单链表

优点

  • 单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制
  • 插入和删除更快,时间复杂度为O(n),在给出某位置的指针后,复杂度仅为O(1)

缺点

  • 查找效率比顺序存储结构差,时间复杂度为O(n)

package com.company;

/**
 * @author wsh
 */
public class Main {

    public static void main(String[] args) {
        LinkArr linkArr = new LinkArr();
        String data = "31,21,17,16,15,26,5,14,23,12,19,30,27,95,22,44,66,99,39";
//        String data = "31,21,17,16";
        linkArr.headInit(data.split(","));
        linkArr.out("头插法初始化输出");
        linkArr.lastInit(data.split(","));
        linkArr.out("尾插法初始化输出");
        linkArr.insert(100,22);
        linkArr.out("在第100插入22后输出");
        linkArr.insert(0,33);
        //这里插入index=-1  也会插在第一个位置
        linkArr.out("在第0插入33后输出");
        linkArr.delete(99);
        linkArr.out("删除第99个后输出");
        linkArr.delete(5);
        linkArr.out("删除第5个后输出");

    }

}

class LinkArr{
    private   static Node  rootNode= new Node();
    /**
     * 插入第i个
     */
    public void insert(int index, int value) {
        int k=1;
        Node p = rootNode;
        //找到位置
        while (p.nextNode!=null&&k < index) {
            p = p.nextNode;
            k++;
        }
        //插入
        Node n = new Node();
        n.data = value;
        n.nextNode=p.nextNode;
        p.nextNode = n;
    }

    public void delete(int index) {
        int k=1;
        Node p = rootNode;
        //找到位置
        while (p.nextNode!=null&&k < index) {
            p = p.nextNode;
            k++;
        }
        Node nextNode = p.nextNode;
        if (nextNode == null||k>index) {
            System.out.println("删除"+index+"失败");
        }else{
            p.nextNode = nextNode.nextNode;
        }
    }


    /**
     *  头插法 初始化
     *  新建一个节点A, 设置下个节点null B
     *  "插入"在 A和B之间
     */
    public void headInit(String [] data){
        rootNode.data = null;
        rootNode.nextNode=null;
        for (String datum : data) {
            Node n = new Node();
            n.data = Integer.parseInt(datum);
            n.nextNode = rootNode.nextNode;
            rootNode.nextNode = n;
        }
    }

    /**
     * 使用尾插法初始化
     * 借助变量p  使其指向 当前链表的最后一个节点
     * 新节点 "接" 上p
     * p再指向这个新节点
     */
    public void lastInit(String[] data){
        //头节点空数据
        rootNode.data = null;
        Node p = rootNode;
        for (String datum : data) {
            Node n = new Node();
            n.data = Integer.parseInt(datum);
            p.nextNode=n;
            p=n;
        }
        //二更
        //在单链表时觉得下面这行可有可无
        //书本上写表示当前链表结束,可能更为准确
        //在后续学习中,当变成循环链表时尤为重要
        p.nextNode=null;
    }

    public void out(String str){
        System.out.print(str+" ");
        int i=0;
        Node p = rootNode;
        while ( p.nextNode!= null) {
            //i 变量 为了输出间隔 好辨认
            if(i%5==0) {
                System.out.print(" ");
            }
            i++;
            System.out.print (p.nextNode.data+",");
            p = p.nextNode;
        }
        System.out.println();
    }

}


class Node{
    Integer data;
    Node nextNode;
} 

收获

  • 所谓头插法,始终有一个"头节点",第一次不过是"插入"在头节点和下一个null节点直接,并非新节点下一个指向整个链表头,那叫抢风头,重点名字中有个插字

  • 尾插法,我理解就是排队接入法, 没有什么"插入"的操作,确实新建一个,接上一个尾巴里,然后其中指向尾巴的变量p,指向这个新节点.以此类推

  • delete删除操作,代码p.nextNode = nextNode.nextNode;,例如ABC节点,删除B,让A的直接指向C.我们要做的就是找到B的前一个节点,所以删除代码中循环一直是p.nextNode,从而这样计数当k==index,此时的p变量就是A,p.nextNode就是index也就是B,然后套入代码就是A.nextNode=B.nextNode.nextNode

  • delete删除操作时容易出问题,故添加if (nextNode == null||k>index),涉及到两个方面

  1. 删除index大于链表长度,循环找了一圈,没找到,但是变量p指向了链尾,这样p.nextNode==null,在数组这个错误叫溢出,所以要判断出来
  2. 删除index输入-1或者 0时 ,导致连循环都没有,次数k==1值无变化,纯属捣乱
  3. 拓展一下2的思路,我脑海想 改成k==1不也可以?实时证明当删除index=1时,不满足循环条件,k值无变化,但是确实有index==1这个节点,k==1会导致本该成功的显示删除失败
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值