java 单向链表 双向链表,单向链表、双向链表的简单结构(Java 实现)

链表的基本结构

链表知识的引入:

对于之前我们接触到的数组知识,要想保存多个对象,首先想到的一定是对象数组。

但是数组是一个长度固定的线性结构,一旦内容不足或者过多,都会在成内存资源的浪费,由此引入链表充分解决资源浪费问题。

单链表的基本实现

class Node{

private Node next;//指向下一个结点

private Object data;//结点保存的数据

public Node(Object data){

this.data = data;//对结点进行赋值

}

//private属性需要设置getter setter方法

public Node getNext() {

return next;

}

public void setNext(Node next) {

this.next = next;

}

public Object getData() {

return data;

}

public void setData(Object data) {

this.data = data;

}

}

public class List {

public static void main(String[] args) {

//初始化结点

Node root = new Node("首结点");

Node node1 = new Node("结点A");

Node node2 = new Node("结点B");

Node node3 = new Node("结点C");

//对结点进行next赋值

root.setNext(node1);

node1.setNext(node2);

node2.setNext(node3);

//获取结点的值

getNodeData(root);//当前节点为首结点

}

public static void getNodeData(Node node){

if(node != null){

System.out.println(node.getData());//打印当前节点的值

getNodeData(node.getNext());//递归调用当前节点的写一个节点

}

}

}

运行结果:

2b8ec8528d9ac690c65fd7dfa3568693.png

在以上整个链表的实现过程中可以看出,Node类的核心作用就是实现节点数据保存和节点连接问题。

当用户调用时需要自己进行节点的创建和节点挂载,比较麻烦,所有此时引入一个单独的Link类,通过Link了实现数据保存以及节点关系挂载

引入单独Link类实现双向链表:

//定义Link接口

interface Link{

void add(Object obj);

boolean remove(int index);

boolean set(int index, Object obj);

Object get(int index);

int contains(Object obj);

void clear();

void printLink();

int length();

Object[] toArray();

}

//实现LInk接口

class LinkImpl implements Link{

private Node first;//头结点

private Node last;//尾结点

private int size = 0;//初始化链表长度为0

private class Node{

private Node prev;//前驱节点

private Object data;//节点保存数据

private Node next;//后继节点

//实现节点数据的初始化

public Node(Node prev, Object data, Node next){

super();

this.prev = prev;

this.data = data;

this.next = next;

}

}

@Override

//增加节点

public void add(Object obj) {

Node temp = this.last;

Node newNode = new Node(temp, obj, null);

this.last = newNode;

if(this.first == null){

this.first = newNode;

}else {

temp.next = newNode;

}

this.size++;//链表长度增加

}

@Override

public boolean remove(int index) {

if(!isLinkElement(index)){

return false;

}

Node node = node(index);

if(node == this.first){

if(node == this.last){

node = null;

this.size--;

return true;

}else {

Node temp = this.first;

this.first = node.next;

temp.next = null;

this.first.prev = null;

this.size--;

return true;

}

}

else if(node == this.last){

Node temp = this.last;

this.last = node.prev;

temp.prev = null;

this.size--;

return true;

}

node.next.prev = node.prev;

node.prev.next = node.next;

node.prev = node.next = null;

this.size--;

return true;

}

@Override

public boolean set(int index, Object obj) {

if(isLinkElement(index)){

return false;

}

Node node = node(index);

node.data = obj;

return true;

}

@Override

public Object get(int index) {

if(isLinkElement(index)){

return null;

}

return node(index).data;

}

@Override

//取得当前节点的下标

public int contains(Object obj) {

if(obj == null){

int index = 0;

for(Node x = this.first; x != null; x = x.next){

if(x.data == null){

return index;

}

index++;

}

return -1;

}else {

int index = 0;

for(Node x = this.first; x != null; x = x.next){

if(obj.equals(x.data)){

return index;

}

index++;

}

return -1;

}

}

@Override

//节点删除

public void clear() {

for(Node x = this.first; x != null; ){

Node temp = x.next;

x.prev = x.next = null;

x = temp;

}

this.first = this.last = null;

this.size--;

}

@Override

public void printLink() {

Object[] result = this.toArray();

for(Object object : result){

System.out.println(object);

}

}

@Override

//取得链表长度

public int length() {

return this.size;

}

@Override

public Object[] toArray() {

Object[] result = new Object[size];

int i = 0;

for(Node temp = first; temp != null; temp = temp.next){

result[i++] = temp.data;

}

return result;

}

// 仅用于LinkImpl类内部

private Node node(int index) {

if (index < (size >> 1)) {

Node result = this.first;

for(int i = 0 ; i< index ; i++) {

result = result.next;

}

return result;

}

Node result = this.last;

for(int i = size-1 ; i > index ; i--) {

result = result.prev;

}

return result;

}

private boolean isLinkElement(int index) {

return index>=0 && index

}

}

//定义工厂类,用于用户调用

class Factory{

private Factory(){}

public static Link getLinkInstance(){

return new LinkImpl();

}

}

public class ListTest {

public static void main(String[] args) {

Link link = Factory.getLinkInstance();

link.add("头结点");//节点插入

link.add("结点A");

link.add("结点B");

link.add("结点C");

//link.clear();

System.out.println(link.contains("结点B"));//取得节点下标

System.out.println(link.contains("abc"));

System.out.println(link.length());//取得链表长度

}

}

运行结果:

0d53527e46610e8025f283fa67dae33d.png

标签:Node,index,Java,Object,单向,node,next,链表,return

来源: https://blog.csdn.net/ly52014/article/details/88110106

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值