使用java语言模拟实现单向链表(博言)
最近越来越多的公司开始注重于算法,而算法和数据结构是离不开的。今天
就为大家提供单向链表的实现办法。
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
链表可分为单向链表和双向链表。
一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。
代码中充分的利用递归的方式去实现,将节点类设置为单向链表的内部类。去实现查找某个节点的功能。并且完成对于某个节点的增删改。
/**
* 模拟一个单项列表
*
* @param <T>
*/
public class ListNode<T> {
private int foot; //根节点索引位置
private int count; //代表链表长度
private Node root; //标识根节点
private class Node {
private T data; //数据信息(可以是任意类型)
private Node next; //下一个节点引用
public Node(T data) {
this.data = data;
}
/**
* 增加节点
*/
private void add(T data) {
if (this.next == null) {
this.next = new Node(data);//如果当前节点的next为null,直接创建一个新的节点
} else {
this.next.add(data);//如果当前节点不为空 那就需要利用递归方法 在一个节点后面增加节点
}
}
/**
* 删除节点
*/
public void remove(Node previous, int index) {
if (ListNode.this.foot++ == index) {
previous.next = this.next;
this.next = null;
ListNode.this.count--;
} else {
this.next.remove(this, index);
}
}
/**
* 删除2
*/
public void remove(Node previous, T data) {
if (this.data.equals(data)) {
previous.next = this.next;
this.next = null;
ListNode.this.count--;
return;
} else {
if (this.next != null) {
this.next.remove(this, data);
} else {
return;
}
}
}
/**
* 修改数据--新旧交替旧数据
*/
public void replace(T oldData, T newData) {
if (this.data.equals(oldData)) {
this.data = newData;
} else {
this.next.replace(oldData, newData);
}
}
/**
* 修改数据利用索引修改
*/
public void replace(int index, T newData) {
if (ListNode.this.foot++ == index) {
this.data = newData;
} else {
this.next.replace(index, newData);
}
}
/**
* 查蓄
*/
public T get(int index) {
if (ListNode.this.foot++ == index) {
return this.data;
} else {
return this.next.get(index);
}
}
/**
* 链表中是是否包含某个节点
*/
public boolean contains(T data) {
if (this.data.equals(data)) {
return true;
} else {
return this.next.contains(data);
}
}
}
/**
* 链表构造函数
*/
public ListNode() {
}
//判断链表是否为空
public boolean isEmpty() {
if (count == 0 || this.root == null) {
return true;
} else {
return false;
}
}
//获取链表的长度
public int size() {
return this.count;
}
//添加一个系欸点
public void add(T data) {
if (this.isEmpty()) {
this.root = new Node(data);
} else {
this.root.add(data);
}
this.count++;
}
//删除--按照索引删除
public void remove(int index) {
if (this.isEmpty()) {
return;
}
if (index < 0 || this.count <= index) {
return;
}
if (index == 0) {//删除根节点
this.root = this.root.next;//将第一个节点赋值给头节点
this.count--;
return;
} else {
this.foot = 0;//为什么这里要重新赋值,自己想一下,这里理解了 就简单了
this.root.remove(this.root, index);
}
}
//根据传入的数值删除
public void remove(T data) {
if (this.isEmpty()) {
return;
}
if (this.root.data.equals(data)) { //如果删除的正好是根节点
Node temp = this.root;
this.root = this.root.next;
temp.next = null;
this.count--;
return;
} else {
this.root.remove(this.root, data);
}
}
//修改 -- 根据索引修改
public void replace(int index,T newData){
if(this.isEmpty()){
return;
}
if(index < 0 || this.count <= index){
return ;
}
this.foot = 0;//为什么这里要重新赋值,自己想一下,这里理解了 就简单了
this.root.replace(index, newData);
}
//修改 -- 新老数据替换
public void replace(T oldData,T newData){
if(this.isEmpty()){
return;
}
this.root.replace(oldData, newData);
}
//查询 --- 根据索引查找
public T get(int index){
if(this.isEmpty()){
return null;
}
this.foot = 0;//为什么这里要重新赋值,自己想一下,这里理解了 就简单了
return this.root.get(index);
}
//是否包含
public boolean contains(T data){
if(this.isEmpty()){
return false;
}
return this.root.contains(data);
}
//打印toarray
public Object[] toArray(){
if(this.isEmpty()){
return null;
}
int count=this.count;
Object[] retVal = new Object[count];
for(int i=0;i<count;i++){
retVal[i] = this.get(i);
System.out.println(this.get(i));
}
return retVal;
}
}
下面是测试代码
public static void main(String[] args) {
ListNode<String> myList = new ListNode<String>();
myList.add("a");
myList.add("b");
myList.add("c");
myList.add("d");
myList.add("e");
myList.add("f");
System.out.println("第三个元素是:" + myList.get(2));
myList.remove(2);
System.out.println("删除之后,第三个元素是:" + myList.get(2));
}
大家可以看到,代码中大量使用了递归来实现,主要是想深入的使用一下递归,同时使用递归来实现节省了较多的代码量,而且比较容易理解,单链表的实现到此结束,谢谢观看!