数据结构的链表(java实现链表)

链表

一,链表结构的定义

链表结构是由许多节点构成的,每个节点都包含两部分:

 数据部分:保存该节点的实际数据。

 地址部分:保存的是上一个或下一个节点的地址

二,链表分类

 单向链表  双向链表  双向循环链表

链表的特点

结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻。

访问时只能通过头或者尾指针进入链表,并通过每个结点的指针域向后或向前扫描 其余结点,所以寻找第一个结点和最后一个结点所花费的时间不等。

三,链表的优缺点

优点:数据元素的个数可以自由扩充 、插入、删除等操作不必移动数据,只需修 改链接指针,修改效率较高

优点:数据元素的个数可以自由扩充 、插入、删除等操作不必移动数据,只需修 改链接指针,修改效率较高

单向链表的结构

定义:单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问 要通过从头部开始顺序读取。

 实现单向链表

/**
* 基于链表结构存取元素的方法 API 定义
* @param <E>
*/
public interface MyList<E> {
void add(E element);
E get(int index);
int size();
E remove(int index);
}

创建单向链表类

public class MySinglyLinkedList<E> implements MyList<E> {
/**
* 向链表中添加元素
* @param element
*/
@Override
public void add(E element) {
}
/**
* 根据元素的位置获取元素
* @param index
* @return
*/
@Override
public E get(int index) {
return null;
}
/**
* 获取元素个数
* @return
*/
@Override
public int size() {
return 0;
}
/**
* 根据元素的位置删除元素
* @param index
* @return
*/
@Override
public E remove(int index) {
return null;
}
public static void main(String[] args) {
}
}

创建节点类

class Node<E>{
private E item;//存储元素

private Node next;//存储下一个节点对象的地址

Node(E item,Node next){
   this.item = item;
   this.next = next;
  }
}

实现添加元素的方法

/**
* 根据元素的位置获取元素
* @param index
* @return
*/@Override

public E get(int index) {
/**校验 Index 的合法性**/
this.checkIndex(index);
/**根据位置获取指定节点**/
Node<E> node = this.getNode(index);
/**将该节点中的元素返回**/
return node.item;
}
/**对 Index 进行校验**/
private void checkIndex(int index){
  
 if(!(index >= 0 && index < this.size)){
     throw new IndexOutOfBoundsException("Index: "+index+" Size:"+this.size);
    }
}
/**根据位置获取节点**/
private Node getNode(int index){
  Node<E> node = this.head;
  for(int i=0;i<index;i++){
     node = node.next;
  }
   return node;
}

实现删除元素的方法

public E remove(int index) {
//对 Index 进行合法性校验
this.checkIndex(index);
//根据指定位置获取节点对象
Node<E> node = this.getNode(index);
//获取节点对象中的元素
E item = node.it;
//判断当前节点是否为头节点
if(node.prev ==null){
this.head = node.next;
}else{
//完成当前节点的直接前驱节点与当前节点的直接后继节点的挂接
node.prev.next = node.next;
}
//判断当前节点是否为尾节点
if(node.next == null){
this.tail = node.prev;
}else{
//完成当前节点的直接后继节点与当前节点的直接前驱节点的挂接
node.next.prev = node.prev;
}
//当前节点断掉与它直接前驱节点的连接
node.prev = null;
//当前节点断掉与它直接后继节点的连接
node.next = null;
node.item = null;
//记录元素个数
this.size--;
return item;
}

获取元素的个数

public int size() {
return this.size;
}

实现在双向链表的头添加元素

public void addFirst(E element){
this.linkFirst(element);
}
/**
* 在链表的头添加元素
*
*/
private void linkFirst(E element){
//获取头节点对象
Node head = this.head;
Node node = new Node(null,element,head);
//将新节点定义为头节点
this.head = node;
//判断当前链表中是否有节点如果没有,那么该节点既是头节点也是尾节点
if(head == null){
this.tail = node;
}else{
head.prev = node;
}
//记录元素个数
this.size++;
}

实现在双向链表的尾添加元素

public void addLast(E element){
this.linkLast(element);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值