数据结构之链表
链表 不同于我们之前学的队列与数组,他的特殊在于结点与元素的联系,链表访问的实现在于结点选择,更要的是分清结点与结点连接的元素的关系。
双链表 实现链表的双向访问。
下面是双链表的简单实现
public class LinkNode {
private LinkNode parent;
private LinkNode child;
private Object obj;
public LinkNode(Object obj) {
this.obj = obj;
}
public Object getObject() {
return obj;
}
public LinkNode getParent() {
return parent;
}
public void setParent(LinkNode parent) {
this.parent = parent;
}
public LinkNode getChild() {
return child;
}
public void setChild(LinkNode child) {
this.child = child;
}
}
实现简单的增删查该双链表
public class NodeList {
private static LinkNode head;
private static LinkNode foot = head;
public static void main(String[] args) {
NodeList list = new NodeList();
list.createList();
list.add("新元素0");
list.add("新元素1");
list.add("新元素2");
list.add("新元素3");
list.add(0, "插入元素");
list.modify(3, "修改的");
list.printList(head);
}
/**
* 创建链表
* @return
*/
public void createList() {
}
/**
* 添加元素
* @param obj :插入的元素
*/
public void add(Object obj) {
LinkNode node = new LinkNode(obj);
if(head != null) {
foot.setChild(node);
node.setParent(foot);
foot = node;
} else {
head = node;
foot = head;
}
}
/**
* 插入元素
* @param index : 要插入元素的下标
* @param obj :插入的元素
*/
public void add(int index, Object obj) {
LinkNode node = new LinkNode(obj);//创建新结点
if(index > this.size() || index < 0){
throw new RuntimeException("下标越界") ;
}
if(head == null) {
head = node;
foot = head;
} else {
LinkNode node1 = this.getLinkNode(index);//得到当前位置的结点
LinkNode node2 = node1.getChild();//子结点
//设置新的引用关系
node1.setChild(node);
node.setParent(node1);
node.setChild(node2);
node2.setParent(node);
}
}
/**
* 得到指定下标的元素
* @param index 下标
* @return 结点
*/
public LinkNode getLinkNode(int index){
//System.out.println("<<<<<<"+this.size());
if(index > this.size() || index < 0){
throw new RuntimeException("下标越界") ;
}
if(head == null) {
System.out.println("该链表为空!!!");
return null;
} else {
int i = 0;
LinkNode node = head;
while (i < index) {
node = node.getChild();
i++;
}
//System.out.println(node.getObject());
return node;
}
}
/**
* 删除元素
*/
public void remove() {
if(head == null) {
System.out.println("无效,此链表为空");
} else {
LinkNode node = foot;//得到尾结点
LinkNode node1 = foot.getParent();//得到前个结点
//设置关系
node1.setChild(null);
}
}
/**
* 删除指定元素
* @param index : 元素的下标
*/
public void remove(int index) {
//判断下标
if(index >= this.size() || index < 0){
throw new RuntimeException("下标越界") ;
} else {
if(head == null) {
System.out.println("无效,此链表为空");
} else if(index < this.size() -1 && index > 0){
LinkNode node = this.getLinkNode(index);//得到index的元素
LinkNode node1 = node.getParent();//得到前结点
LinkNode node2 = node.getChild();//得到后结点
//设置关系
node1.setChild(node2);
node2.setParent(node1);
} else {// 删除尾结点
LinkNode no = foot;//得到尾结点
LinkNode no1 = foot.getParent();//得到前个结点
//设置关系
no1.setChild(null);
}
}
}
/**
* 得到链表的大小
* @return 链表的大小
*/
public int size() {
if(head != null) {
int i = 0;
LinkNode node = head;
while(node.getChild() != null) {
i++;
node = node.getChild();
}
return i+1;
} else {
return 0;
}
}
/**
* 更改指定下标的元素
* @param index 下标
* @param obj 新元素
*/
public void modify(int index, Object obj) {
//判断下标
if(index >= this.size() || index < 0){
throw new RuntimeException("下标越界") ;
} else {
LinkNode node = new LinkNode(obj);//创建新结点
if(head == null) {
System.out.println("无效,此链表为空");
} else if(index < this.size() -1){
LinkNode nodeindex = this.getLinkNode(index);//得到index的元素
LinkNode nodeahead = nodeindex.getParent();//得到前结点
LinkNode nodebehind = nodeindex.getChild();//得到后结点
//设置关系
nodeahead.setChild(node);
node.setParent(nodeahead);
node.setChild(nodebehind);
nodebehind.setParent(node);
} else {// 删除尾结点
LinkNode no = foot;//得到尾结点
LinkNode noa = foot.getParent();
noa.setChild(node);
node.setParent(noa);
node.setChild(null);
}
}
}
/**
* 遍历链表
*/
public void printList(LinkNode head) {
if(head != null) {
Object data = head.getObject();
System.out.println(data);
LinkNode temp = head.getChild();
printList(temp);
}
}
}
对于链表结点的操作时比较纠结的,一不小心就很容易混乱,所在使用时必须理清思路,一步步实现。
分享到:
相关推荐
本资料“算法-数据结构之链表合并算法.rar”包含的“数据结构之链表合并算法.pdf”应该详细探讨了这个主题。 首先,链表的基本概念是必不可少的。链表由一系列节点构成,每个节点包含数据元素和指向下一个节点的...
本资料包“数据结构-使用javascript讲解数据结构之链表.zip”将深入探讨链表的概念、实现以及其在JavaScript中的应用。 链表不同于数组,数组是连续的内存空间,而链表的元素在内存中是非连续存储的。每个元素称为...
C语言中数据结构之链表归并排序实例代码 问题 设有两个无头结点的单链表,头指针分别为ha,hb,链中有数据域data,链域next,两链表的数据都按递增排序存放,现要求将hb表归到ha表中,且归并后ha仍递增序,归并中...
链表是一种重要的数据结构,它在计算机科学中扮演着至关重要的角色,特别是在处理动态数据集合时。相较于数组,链表不需预先分配连续的内存空间,因此在插入和删除操作上具有更高的灵活性。本主题主要关注C#语言中的...
线性表的存储结构使用链表。 2、提供操作:自表首插入元素、删除指定元素、搜索表中是否有指定元素、输出链表。 3、接收键盘录入的一系列整数(例10,25,8,33,60)作为节点的元素值,创建链表。输出链表内容。 4、输入...
链表是一种基础且重要的数据结构,它在计算机科学中扮演着关键角色,特别是在处理动态数据集合时。相较于数组,链表允许更灵活的内存管理,因为它不需要预先分配连续的存储空间。下面,我们将深入探讨链表的概念、...
链表数据结构知识点 链表是一种基本的数据结构,它是一种非顺序存储结构,通过指针将各个节点连接起来,每个节点都包含了数据和指向下一个节点的指针。链表的优点是可以动态地增减节点,插入和删除节点的时间复杂度...
在C语言中,链表是一种基础且重要的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。上述文件中包含了几个关于链表操作的C语言源代码范例,主要涉及链表的创建、遍历以及按序号查找节点。 ...
链表、栈和队列是计算机科学中基础且重要的数据结构,它们在程序设计和算法实现中发挥着关键作用。本文将深入探讨这些概念,并结合实际应用进行解析。 首先,我们要理解链表的基本原理。链表不同于数组,它不是连续...
### 数据结构之链表详解 #### 一、链表基本概念 **链表**是一种常见的数据结构,它通过一组地址不连续的存储单元来存储线性表中的各个数据元素。链表中的每个元素称为**结点**,这些结点不仅包含实际的数据信息,...
1.使用Python语言实现链表数据结构 2.基于类封装思想 3.实现链表增删改查功能 4.有测试数据
数据结构顺序链表的实现数据结构顺序链表的实现数据结构顺序链表的实现数据结构顺序链表的实现数据结构顺序链表的实现数据结构顺序链表的实现
链表是一种线性数据结构,它由一系列节点构成。每个节点通常包含两部分信息:一部分是存储的数据本身,另一部分是指向下一个节点的指针(或引用)。链表的特点在于它不像数组那样需要连续的内存空间,节点间的连接...
在IT领域,数据结构是计算机科学中的核心概念之一,它涉及到如何有效地组织和管理大量数据。链表作为基本的数据结构类型,广泛应用于各种算法和程序设计中。本话题聚焦于链表的应用,具体来说,是利用链表实现一元...
本文将深入探讨一种特殊的数据结构表示——三叉链表表示的二叉树。这种表示方式在C++语言中尤为常见,它允许我们高效地创建、插入、删除节点以及进行循环算法遍历二叉树。 首先,我们要理解什么是二叉树。二叉树是...
在C++中,链表是一种常见的数据结构,它不同于数组,不需要连续的内存空间来存储元素。本项目专注于C++实现的单链表,提供了一个完整的可运行示例,包括`main.cpp`主程序,以及`linklist.h`和`node.h`两个头文件,...
单链表 单循环链表 双链表 双循环链表 内容学习于 https://www.bilibili.com/video/BV1W64y1z7jh?p=19&spm_id_from=pageDriver&vd_source=4d33bf4ac4499f2c0370694554a02fa5
C++数据结构之链表的创建 前言 1.链表在C/C++里使用非常频繁, 因为它非常使用, 可作为天然的可变数组. push到末尾时对前面的链表项不影响. 反观C数组和std::vector, 一个是静态大小, 一个是增加多了会对之前的元素...