链表的数据结构关键在于节点知道它下一个节点是谁,故需要在节点类中定义next字段来存储下一个节点。其增删改查均建立在这一关系之上。
除ROOT节点在增删操作需要稍许特殊处理外,其他节点 点点平等。代码如下:
package LinkListTest;
interface ILink<T> {
//新增节点
void Add(T data);
//删除节点
void Remove(T data);
//设置节点数据
void SetData(int index, T data);
//获取指定位置节点数据
T GetData(int index);
//判断是否包含节点
boolean Contains(T data);
//获取链表长度
int Size();
//判断列表是否为空
boolean IsEmpty();
//将列表转为数组输出
Object[] ToArray();
//清空列表
void Clean();
}
class LinkImpl<T> implements ILink<T> {
class Node {
private T data;
private Node next;
Node(T data) {
this.data = data;
}
//递归查找最后一个空节点,将新增节点添加至空节点
void addNode(Node node) {
if (this.next == null) {
this.next = node;
} else {
this.next.addNode(node);
}
}
//将每一个节点数据递归放入返回数组内
void toArrayData() {
LinkImpl.this.retArray[LinkImpl.this.foot++] = this.data;
if (this.next != null) {
this.next.toArrayData();
}
}
//如当前节点index与指定index相同,返回当前节点数据,否则递归至下一个节点进行判断
T getData(int index) {
if (LinkImpl.this.foot++ == index) {
return this.data;
} else {
return this.next.getData(index);
}
}
//通过递归查找到指定index的位置,再将data更新至指定节点
void setData(int index, T data) {
if (LinkImpl.this.foot++ == index) {
this.data = data;
} else {
this.next.setData(index, data);
}
}
//判断当前节点的值是否与指定值相同,不同则递归至下一个节点进行判断
boolean containsData(T data) {
if (data.equals(this.data)) {
return true;
} else if (this.next == null) {
return false;
} else {
return this.next.containsData(data);
}
}
//如当前节点的数据与要删除的数据相同,则当前节点上一个节点的next指向当前节点的next,否则递归至下一个节点进行相同操作
void RemoveData(Node previousNode, T data) {
if (data.equals(this.data)) {
previousNode.next = this.next;
} else {
if (this.next != null) {
this.next.RemoveData(this, data);
}
}
}
}
private Node root;
private int count;
private int foot;
private Object[] retArray;
@Override
public void Add(T data) {
if (data == null) {
return;
}
Node node = new Node(data);
if (root == null) {
root = node;
} else {
root.addNode(node);
}
this.count++;
}
@Override
public int Size() {
return this.count;
}
@Override
public boolean IsEmpty() {
return this.count == 0;
}
@Override
public Object[] ToArray() {
if (IsEmpty()) {
return null;
}
this.foot = 0;
retArray = new Object[this.count];
this.root.toArrayData();
return retArray;
}
@Override
public T GetData(int index) {
if (index >= this.count) {
return null;
}
this.foot = 0;
return root.getData(index);
}
@Override
public void SetData(int index, T data) {
if (index >= this.count) {
return;
}
this.foot = 0;
root.setData(index, data);
}
@Override
public boolean Contains(T data) {
if (data == null) {
return false;
}
return this.root.containsData(data);
}
@Override
public void Remove(T data) {
if (this.Contains(data)) {
if (data.equals(this.root.data)) {
this.root = this.root.next;
} else {
this.root.next.RemoveData(this.root, data);
}
this.count--;
}
}
@Override
public void Clean() {
this.root = null;
this.count = 0;
}
}
public class LinkDemo {
public static void main(String[] args) {
LinkImpl<String> stringLink = new LinkImpl<String>();
System.out.println(stringLink.Size() + " " + stringLink.IsEmpty());
stringLink.Add("Hello");
stringLink.Add("World");
stringLink.Add("DXD");
stringLink.Remove("World");
System.out.println(stringLink.Size() + " " + stringLink.IsEmpty());
for (var item : stringLink.ToArray()) {
System.out.println(item);
}
System.out.println("--------修改数据-----------------------");
System.out.println(stringLink.GetData(0));
System.out.println(stringLink.GetData(1));
System.out.println(stringLink.GetData(4));
stringLink.SetData(1, "世界");
for (var item : stringLink.ToArray()) {
System.out.println(item);
}
System.out.println("--------判断数据存在-----------------------");
System.out.println(stringLink.Contains("Hello"));
System.out.println(stringLink.Contains("WXL"));
//链表清空
System.out.println("--------链表清空-----------------------");
stringLink.Clean();
System.out.println(stringLink.IsEmpty());
}
}
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。