N日一篇——Java实现链式表
Posted 从零开始的智障生活
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了N日一篇——Java实现链式表相关的知识,希望对你有一定的参考价值。
线性表详解:https://blog.csdn.net/qq_34028001/article/details/119321938
一、建立单向链表数据类型
package com.zyx.Linear.LinkedList;
/**
* 定义一个链表的抽象数据类型ADT
* @author zyx
*/
public interface LinkedList {
//判断当前节点是否为空,空则返回true
public boolean isEmpty(SingleLinkedList L);
// 创建一个结点
public SingleLinkedList createNewNode(int data);
//插入结点:直接插入到尾部
public void insertNodetoRear(SingleLinkedList L,int data);
//插入结点:按位序插入结点,从1开始计,插入到第i个位置,即将第i个往后移一下,挪出一个位置。
public void insertNodebyLocate(SingleLinkedList L,int locate,int data);
//删除结点:按位序删除,从1开始计,删除第i个位置内存,并将第i+1个往前移一下,挪出一个位置。
public void deleteNodebyLocate(SingleLinkedList L,int locate);
//删除结点:按值删除
public void deleteNodebyValue(SingleLinkedList L,int data);
//结点访问:按key值访问,这里数据只有一个data,所以只用data,返回位序
public int accessNodebyValue(SingleLinkedList L,int data);
//结点访问:按位序访问,返回数据data值。
public int accessNodebyLocate(SingleLinkedList L,int locate);
//打印线性表内容
public void printList(SingleLinkedList L);
//返回线性表长度
public int Length(SingleLinkedList L);
//销毁线性表L
public void destroyList(SingleLinkedList L);
}
二、实现单向链表
package com.zyx.Linear.LinkedList;
/**
* 实现一个单向链表
* 一个单向链表的字段只有数据项和后继结点,当然如果想的话可以直接设置一个参数length来统计链表长度。
*/
public class SingleLinkedList implements LinkedList{
private int data;
private SingleLinkedList next;
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public SingleLinkedList getNext() {
return next;
}
public void setNext(SingleLinkedList next) {
this.next = next;
}
// 初始化一个带头结点的单链表
public SingleLinkedList() {
setData(-1); //头结点无有效数据,用-1表示
setNext(null);
}
@Override
public SingleLinkedList createNewNode(int data) {
SingleLinkedList newNode = new SingleLinkedList();
newNode.setData(data);
return newNode;
}
@Override
public void insertNodetoRear(SingleLinkedList L, int data) {
// 首先判断传入的单链表不为空
if(isEmpty(L) == true)return;
// 设置一个当前节点用于遍历
SingleLinkedList curNode = L;
// 遍历到最后一个结点
while(curNode.getNext() != null) {
curNode = curNode.getNext();
}
// 用传进来的数据创建一个新节点
SingleLinkedList newnode = createNewNode(data);
// 将新的结点放到最后
curNode.setNext(newnode);
}
@Override
public void insertNodebyLocate(SingleLinkedList L, int locate, int data) {
// 首先判断传入的单链表不为空
if(isEmpty(L) == true)return;
// 判断传入的位序是否>0
if(locate<1) {
System.out.println("传入位序<1,按位序插入结点失败");
return;
}
// 设置一个当前节点用于遍历
SingleLinkedList curNode = L;
// 设置一个位序临时字段,记录当前位序
int curi=0;
//特殊情形:locate,超过已有数据长度+1,即:即使想要作为尾结点也没办法
if(locate>Length(L)+1) {
System.out.println("给的位序超过已有数据长度+1,插入失败");
return;
}
// 找到位序为locate的结点前一个结点
while(curi != locate-1) {
curNode=curNode.getNext(); //从头结点的子节点,即位序为1的结点,开始遍历
curi++;
}
// 用传进来的数据创建一个新节点
SingleLinkedList newnode = createNewNode(data);
// 如果位置合理,实现在单向链表的某个位置插入这个节点
newnode.setNext(curNode.getNext()); //将原位序为i的结点接在新节点后面,相当于后移
curNode.setNext(newnode); //将新节点接在位序为i-1的结点的后面。
}
@Override
public void deleteNodebyLocate(SingleLinkedList L, int locate) {
SingleLinkedList curNode = L; // 带头结点,所以从头结点的子节点计
//特殊情形:locate,超过已有数据长度,即:即使想要作为尾结点也没办法
if(locate>Length(L)) {
System.out.println("给的位序超过已有数据长度,删除失败");
return;
}
// 遍历到第locate结点的父结点
for(int i = 1;i<locate;i++) {
curNode=curNode.getNext();
}
// 将locate的父节点与locate的子节点相连
curNode.setNext(curNode.getNext().getNext());
}
@Override
public void deleteNodebyValue(SingleLinkedList L, int data) {
// TODO Auto-generated method stub
return;
}
@Override
public int accessNodebyValue(SingleLinkedList L, int data) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int accessNodebyLocate(SingleLinkedList L, int locate) {
// TODO Auto-generated method stub
return 0;
}
@Override
public void printList(SingleLinkedList L) {
SingleLinkedList curNode = L.getNext();
while(curNode != null) {
System.out.println(curNode.getData());
curNode = curNode.getNext();
}
}
@Override
public int Length(SingleLinkedList L) {
/**
* 头结点不计,计带有有效数据的结点
*/
int i=0;
SingleLinkedList curNode = L;
while(curNode.getNext() != null) {
curNode=curNode.getNext();
i++;
}
return i;
}
@Override
public void destroyList(SingleLinkedList L) {
// TODO Auto-generated method stub
}
@Override
public boolean isEmpty(SingleLinkedList L) {
// TODO Auto-generated method stub
if(L == null) {
System.out.println("传入单链表为空,无法插入结点");
return true;
}
return false;
}
}
三、测试单向链表
package com.zyx.Linear.LinkedList;
public class TestSLL {
public static void main(String[] args) {
// TODO Auto-generated method stub
SingleLinkedList sll = new SingleLinkedList();
System.out.println("插入结点直接插入到尾部,值设为1~3");
for(int i=1;i<4;i++) {
sll.insertNodetoRear(sll,i);
}
sll.printList(sll);
System.out.println("再插入结点,按位序4~6插入,值设为4~6");
for(int i=4;i<7;i++) {
sll.insertNodebyLocate(sll, i, i);
}
sll.printList(sll);
System.out.println("再删除结点,按位序删除,删除位序为3的结点(删完之后,原链表长度减一),以及位序为7(不存在)的结点");
sll.deleteNodebyLocate(sll, 3);
sll.deleteNodebyLocate(sll, 7);
sll.printList(sll);
}
}
运行结果:
插入结点直接插入到尾部,值设为1~3
1
2
3
再插入结点,按位序4~6插入,值设为4~6
1
2
3
4
5
6
再删除结点,按位序删除,删除位序为3的结点(删完之后,原链表长度减一),以及位序为7(不存在)的结点
给的位序超过已有数据长度,删除失败
1
2
4
5
6
以上是关于N日一篇——Java实现链式表的主要内容,如果未能解决你的问题,请参考以下文章