:链表 -- 链表介绍单链表
Posted CodeJiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了:链表 -- 链表介绍单链表相关的知识,希望对你有一定的参考价值。
1. 链表介绍
好好学链表,链表是图和树的基础。
1.1 为什么会出现链式存储?
顺序存储虽然是一种很有用的数据结构,但它具有如下局限性:
- 若要为线性表扩充存储空间,则需要重新创建一个地址连续的更大的存储空间,并把原有的数据都复制到心的存储空间中。
- 因为顺序表要求逻辑上相邻的数据元素,在物理存储位置上也是相邻的,这就使得要增删改查数据元素会引起约一半的数据元素的移动。
所以:
顺序表适合存储“静态”线性表,即线性表一旦形成后,就很少进行插入与删除操作。对于需要
频繁执行插入和删除操作的“动态”线性表,通常采用链式存储结构,链式存储结构不要求逻辑
上相邻的数据元素物理元素也相邻,它是用一组地址任意的存储单元来存放数据元素的值。
因此,链式存储结构没有顺序存储结构所具有的在某些操作上面的局限性,但却失去了可以
随机存取的特点(可以插在任意位置,只要数组下标不越界),在链式存储结构上只能进行顺序存取(存储在next域)。
1.2 单链表的定义
1.3 链表在内存中的存储结构(真实的物理存储结构)
链表是有序的列表,但是它在内存中是存储如下
1.4 单链表(带头结点) 逻辑结构示意图如下
由图可知,单链表是通过指向后继结点的指针把它的一串结点连接成一个链。
头指针:线性表中第一个元素的存储地址。
一个单链表就是由它的头指针head来唯一标识它。
为了操作方法,在第一个结点之前虚加一个“头结点”,头结点的数据域一般不存放数据,
指针域存放指向第一个结点(也叫做“首结点”)的指针。
若线性表为空表,则头结点的指针域为“空”。
单链表的最后一个结点(尾结点)的指针域为“空”。
1.5 单链表(带头结点)实现的思路分析
1.5.1 初始状态:
1.5.2 添加结点
现在在s1和s2之间插入一个s3
为了方便对比,现在演示不带头结点的单链表表头位置进行插入
- 插入前
- 插入后
1.5.4 添加结点补充
添加结点补充:
- 头插法:每次添加结点添加在头结点的next域
- 尾插法:每次添加结点添加到当前单链表的表尾
1.5.3 删除结点
- 删除前
- 删除后(删除s3)
被删除的节点,将不会有其它引用指向,会被垃圾回收机制回收
补充:上面的删除思路有点问题 因为实际我并不知道S3后面是S2。所以最好的删除语句是:
s1.next = s1.next.next
1.6 单链表示例
根据带有头部的单链表,实现商品增删改查,并且也可以针对商品已编号进行排序,完成排行榜。
GoodsNode.java
package data_structure;
public class GoodsNode
public int id;
public String name;
public double price;
public GoodsNode next;
public GoodsNode(int id, String name, double price)
this.id = id;
this.name = name;
this.price = price;
@Override
public String toString()
return "GoodsNode" +
"id=" + id +
", name='" + name + '\\'' +
", price=" + price +
'';
DLLinkedList.java
package data_structure;
public class DLLinkedList
// 头结点
private final GoodsNode node = new GoodsNode(0, "", 0.0);
/**
* 往链表中添加结点
*/
public void add(GoodsNode goodsNode)
GoodsNode temp = node;
while (temp.next != null)
temp = temp.next;
temp.next = goodsNode;
/**
* 按照商品编号id值进行添加,从小到大的顺序添加
*/
public void addOrder(GoodsNode goodsNode)
GoodsNode temp = node;
boolean flg = false;
while (true)
if (temp.next == null)
break;
if (temp.next.id > goodsNode.id)
break;
else if (temp.next.id == goodsNode.id)
flg = true;
break;
temp = temp.next;
if (flg)
System.out.println("已经存在了该商品,不能添加重复元素");
else
goodsNode.next = temp.next;
temp.next = goodsNode;
/**
* 修改结点
* 1.先找到链表中目标结点,
* 2.根据新的数据修改
* 3.根据商品编号进行查找,
*/
public void updateNode(GoodsNode goodsNode)
/*
* 如果链表空
*/
if (node.next == null)
System.out.println("链表为空...");
return;
GoodsNode temp = node.next;
//标识符,表示找到了结点
boolean flg = false;
while (true)
if (temp == null)
break;
if (temp.id == goodsNode.id)
flg = true;
break;
temp = temp.next;
if (flg)
//真正的修改结点
temp.name = goodsNode.name;
temp.price = goodsNode.price;
else
System.out.println("在整个链表中未找到目标节点...");
/**
* 结点删除功能
* 条件:根据结点的编号删除
*/
public void delNode(int id)
GoodsNode temp = node;
boolean flg = false;
while (true)
if (temp.next == null)
break;
if (temp.next.id == id)
flg = true;
break;
temp = temp.next;
if (flg)
temp.next = temp.next.next;
else
System.out.println("未找到删除的结点...");
/**
* 定义查看链表中每一个结点元素
*/
public void list()
if (node.next == null)
System.out.println("空链表");
return;
GoodsNode temp = node.next;
while (temp != null)
System.out.println(temp);
temp = temp.next;
Test.java
package data_structure;
public class Test
public static void main(String[] args)
GoodsNode goodsNode1 = new GoodsNode(1, "1号装备", 100);
GoodsNode goodsNode2 = new GoodsNode(2, "2号装备", 200);
GoodsNode goodsNode3 = new GoodsNode(3, "3号装备", 300);
GoodsNode goodsNode4 = new GoodsNode(4, "4号装备", 400);
DLLinkedList list = new DLLinkedList();
/* list.add(goodsNode1);
list.add(goodsNode2);
list.add(goodsNode3);
list.add(goodsNode4);*/
list.addOrder(goodsNode3);
list.addOrder(goodsNode1);
list.addOrder(goodsNode4);
list.addOrder(goodsNode2);
list.list();
System.out.println();
list.updateNode(new GoodsNode(1, "最好的商品", 10000));
list.list();
运行结果:
1.7 补充:面试题,统计单链表中结点个数
下面的代码是上面DLLinkedList类里面新增的一个方法。
/**
* 面试题
* 计算单链表中存在的节点个数
* 不统计头结点
*/
public int getLength()
if (node.next == null)
System.out.println("空链表");
return 0;
GoodsNode temp = node.next;
int length = 0;
while (temp != null)
//结点个数
length++;
temp = temp.next;
return length;
以上是关于:链表 -- 链表介绍单链表的主要内容,如果未能解决你的问题,请参考以下文章