单链表,我来了

一、单链表的特点

链表以结点作为存储单元,这些存储单元可以是不连续的。单链表每个结点由两部分组成:存储的数值+后序结点的指针,下面均是单链表的操作。

在这里插入图片描述
上面展示的是一个单链表的存储原理图,简单易懂,head为头节点,他不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用,而每个节点中都有一个next引用,指向下一个节点,就这样一节一节往下面记录,直到最后一个节点,其中的next指向null。(网络引用)

二、实战(废话不多说,直接上机开干)

class Node {
  ///数据域
  int data;

  下一个结点
  Node next;

  Node(int data){
    this.data = data;
  }
}
class LinkList {
  Node head;

 void addNode(Node data) {
    if (head == null) {
      head = data;
      return;
    }
    Node temp = head;
    while (temp.next != null) {
      temp = temp.next;
    }
    temp.next = data;
  }

  ///插入到指定位置
  void insertNodeByIndex(int index, Node newNode) {
    if (index < 0 || index > getLength()) {
      print("插入位置不合法");
    }
    if (head == null) {
      head = newNode;
      return;
    }
    int len = 0;
    Node temp = head;
    while (temp.next != null) {
      len++;
      if (len == index) {
        newNode.next = temp.next;
        temp.next = newNode;
        break;
      }
      temp = temp.next;
    }
  }

  Node removeAt(int index) {
    if (index < 0 || index > getLength()) {
      return null;
    }
    if (head == null) {
      return null;
    }
    if (index == 0) {
      //删除头结点
      head = head.next;
      return head;
    }
    Node temp = head;
    Node delNode;
    int len = 0;
    while (temp.next != null) {
      len++;
      if (len == index) {
        delNode = temp.next;
        temp.next = temp.next.next;
        break;
      }
      temp = temp.next;
    }
    return delNode;
  }

  bool remove(Node node) {
    if (node == null) {
      return false;
    }
    if (head == null) {
      return false;
    }
    if (node.data == head.data) {
      //删除头结点
      head = head.next;
      return true;
    }
    Node temp = head;
    bool isSuccess = false;
    while (temp.next != null) {
      if (temp.next.next == node.next) {
        temp.next = node.next;
        isSuccess = true;
        break;
      }
      temp = temp.next;
    }
    return isSuccess;
  }

  int getLength() {
    if (head == null) {
      return 0;
    }
    int len = 0;
    Node temp = head;
    while (temp.next != null) {
      temp = temp.next;
      len++;
    }
    return len;
  }

  ///查找元素
  Node findNodeByIndex(int index) {
    if (index < 0 || index > getLength()) {
      return null;
    }
    if (head == null) {
      return null;
    }
    Node temp = head;
    for (int i = 0; i < index; i++) {
      temp = temp.next;
    }
    return temp;
  }

  ///遍历
  void printLink() {
    Node curNode = head;
    while (curNode != null) {
      print(curNode.data);
      curNode = curNode.next;
    }
  }
}

测试类

  LinkList list = new LinkList();
  Node node1 = Node(1);
  Node node2 = Node(2);
  Node node3 = Node(3);
  list.addNode(node1);
  list.addNode(node2);
  list.addNode(node3);
  Node node4 = Node(4);
  list.insertNodeByIndex(1, node4);
  print("删除前:");
  list.printLink();
  list.remove(node4);
  print("删除的元素:${list.removeAt(1).data}");
  print("删除后:");
  list.printLink();
  print("查找元素:${list.findNodeByIndex(1).data}");

三、链表的总结

单链表、循环链表、双向链表的比较

链表结构优点缺点
单链表1、在找出节点后,插入和删除速度相较于顺序表更快 2、不需要预分配空间,元素个数不受限制查找数据元素的速度相较于顺序表更慢
循环链表在单链表的基础上进一步改进,遍历的时候可以从任意结点开始,增加了遍历的灵活性没有解决单链表查找元素速度较慢的问题
双向链表在单链表的基础上进一步改进,查找元素可以反向查找前缀结点,一定程度上提升了查找数据元素的速度需要记录前缀结点,增加了额外的内存空间开销
静态链表在插入和删除操作时,不需要移动元素,只需要修改游标,改进 了顺序表插入和删除需要移动元素的缺点1、没有解决顺序表表长难以确定的问题 2、失去了顺序表随机存储的特性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值