单链表
什么是单链表
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。
┌───┬───┐
│data │next │
└───┴───┘
data域–存放结点值的数据域
next域–存放结点的直接后继的地址(位置)的指针域(链域)
链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的,每个结点只有一个链域的链表称为单链表(Single Linked List)。
单链表与顺序表的区别(优缺点)
开辟空间的方式
顺序表是一次开辟,不可加(动态分配除外)
链表为动态分配,可在加空间。
空间利用率
顺序表的空间利用率显然要比链表高。因为链表需要一个空间存储指针域。
时间复杂度
主要涉及访问元素的操作,元素的插入、删除和移动操作极少,选择顺序表。
主要涉及元素的插入、删除和移动,访问元素的需求很少,选择链表。
单链表的应用场景
在数据需要频繁进行插入、删除等操作时,选择链表要比线性表要合理。
代码示例
package com.practise.linkedlist;
public class SingleLinkedList {
public static void main(String[] args) {
HeroNode hero1 = new HeroNode(1,"宋江","及时雨");
HeroNode hero2 = new HeroNode(2,"吴用","智多星");
HeroNode hero3 = new HeroNode(3,"卢俊义","玉麒麟");
HeroNode hero4 = new HeroNode(4,"林冲","豹子头");
LinkedList linkedList = new LinkedList();
// linkedList.add(hero1);
// linkedList.add(hero2);
// linkedList.add(hero3);
// linkedList.add(hero4);
linkedList.addByOrder(hero1);
linkedList.addByOrder(hero4);
linkedList.addByOrder(hero3);
linkedList.addByOrder(hero2);
System.out.println("修改前----------");
linkedList.show();
HeroNode hero5 = new HeroNode(4,"林冲","豹子头!!");
linkedList.update(hero5);
System.out.println("修改后----------");
linkedList.show();
System.out.println("删除前----------");
linkedList.delete(2);
System.out.println("删除后----------");
linkedList.show();
}
}
class LinkedList{
private HeroNode head = new HeroNode(0,"","");
//顺序添加结点到单链表(尾插)
public void add(HeroNode heroNode){
//因为head结点不能动,需要定义一个temp来遍历
HeroNode temp = head;
//遍历链表,找到最后
while (true){
if(temp.next == null){
break;
}
temp = temp.next;
}
temp.next = heroNode;
}
//删除结点
//思路:找到待删除结点的前一个结点
public void delete(int no){
HeroNode temp = head;
//是否能找到目标结点
boolean flag = false;
while (true){
if (temp.next == null){
break;
}
if (temp.next.no == no){
flag = true;
break;
}
temp = temp.next;
}
if (flag){
temp.next = temp.next.next;
}else{
System.out.printf("没找到编号为%d的结点!\n",no);
}
}
//修改结点信息,根据no修改,no不可改变
public void update(HeroNode newHeroNode){
if (head.next == null){
System.out.println("链表为空!");
return;
}
HeroNode temp = head.next;
boolean flag = false;
while (true){
if (temp == null){
break;
}
if (temp.no == newHeroNode.no){
flag = true;
break;
}
temp = temp.next;
}
//如果找到对应编号的结点,则修改对应的数据
if (flag){
temp.name = newHeroNode.name;
temp.nickname = newHeroNode.nickname;
}else{
System.out.printf("没有找到编号%d的结点,不能修改!\n",newHeroNode.no);
}
}
//根据编号添加
public void addByOrder(HeroNode heroNode){
HeroNode temp = head;
boolean flag = false;
while(true){
if (temp.next == null){
break;
}
if (temp.next.no > heroNode.no){
break;
}else if (temp.next.no == heroNode.no){
flag = true;
break;
}
temp = temp.next;
}
if (flag){ //不能添加
System.out.printf("准备插入的英雄编号%d已经存在,不能加入\n",heroNode.no);
}else{
heroNode.next = temp.next;
temp.next = heroNode;
}
}
//显示链表
public void show(){
if(head.next == null){
System.out.println("链表为空!");
return;
}
HeroNode temp = head.next;
while(true){
if (temp == null){
break;
}
System.out.println(temp);
temp = temp.next;
}
}
}
class HeroNode{
public int no;
public String name;
public String nickname;
public HeroNode next;
public HeroNode(int no,String name,String nickname){
this.no = no;
this.name = name;
this.nickname = nickname;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
}