今天写一个简单的单链表,作为小白的我可能会犯一些错误要是有大佬看到啦还麻烦指出哦。
1.创建一个链表
public class LinkedNode {
public int data;
public LinkedNode next = null;
}
2.我们先来写头插法
头插法很简单,就是直接在链表头部进行插入数据
public void addFirst(int data) {
LinkedNode node = new LinkedNode();
node.data = data;
if (this.head == null) {
this.head = node;
return;
}
node.next = head;
this.head = node;
return;
}
3.接下来是尾插法
尾插法先判断头结点是否为空,然后通过循环找到最后一个节点
public void addLast(int data) {
LinkedNode node = new LinkedNode();
node.data = data;
if (this.head == null) {
this.head = node;
return;
}
//需要先找到最后一个节点
LinkedNode cur = this.head;
while (cur.next != null) {
cur = cur.next;
}
cur.next = node;
}
4.我们既然已经有了头插法还有尾插法啦那就等于有了一个链表啦,那我们该怎么把这个链表打印出来呢,方法很简单就是将其遍历一遍即可
public void display() {
System.out.print("[");
for (LinkedNode node = this.head; node != null; node = node.next) {
System.out.print(node.data);
if (node.next != null) {
System.out.print(",");
}
}
System.out.println("]");
}
5.一个不能插入数据的链表不是一个好的链表哦,加下来我们对其进行加工让他可以拥有插入操作
要进行插入,首先得找一个节点,那么这个节点肯定得有范围限制
当这个节点不在链表范围内则直接返回
当这个节点为零时直接使用头插法
当这个节点等于数组长度时使用尾插法
当不是以上三种情况时先找到这个节点的前一个位置进行操作
具体过程如下
public void addIndex(int index, int data) {
if (index < 0 || index > size()) {
return;
}
if (index == 0) {
addFirst(data);
return;
}
if (index == size()) {
addLast(data);
return;
}
LinkedNode node = new LinkedNode();
node.data = data;
//找到index位置节点的前一个节点pre
LinkedNode pre = getIndexpos(index - 1);
node.next = pre.next;
pre.next = node;
}
6.上面刚刚提到链表长度,那么我们还得写一个求长度的
方法也很简单就是将其遍历即可。
public int size() {
int size = 0;
for (LinkedNode node = this.head; node != null; node = node.next) {
size++;
}
return size;
}
7.如果想查找关键字是否在链表中那该如何去做呢
同样是进行遍历,然后进行查找
public boolean contanins(int key) {
//遍历链表
for (LinkedNode cur = this.head; cur != null; cur = cur.next) {
if (cur.data == key) {
return true;
}
}
return false;
}
8.是不是该写删除的方法了
话不多说直接上代码
//删除第一次出现关键字为key的节点
public void remove(int toRemove) {
//删除元素核心是得找到目标元素的前一个位置
//先判断空链表情况
if (head == null) {
return;
}
//先考虑是不是头结点
if (head.data == toRemove) {
this.head = this.head.next;
return;
}
//删除中间节点,找到要删除元素的前一个元素
LinkedNode pre = searchPre(toRemove);
if (pre != null) {
pre.next = pre.next.next;
} else {
System.out.println("没有这个数据");
return;
}
}
//删除链表中所有出现的这个数
public void removeAll(int toRemove) {
if (head == null) {
return;
}
while (searchPre(toRemove) != null) {
remove(toRemove);
}
}
9.好像就剩个查找一个数是不是在链表里面,同样还是遍历的方法
private LinkedNode searchPre(int toRemove) {
LinkedNode prev = this.head;
while (prev.next != null) {
if (prev.next.data == toRemove) {
return prev;
}
prev = prev.next;
}
return null;//表示没找到
}
10.最后就是清空链表的操作
很简单直接令头结点为空即可
public void clear() {
head = null;
}
上面写的比较分散,将代码整合一下吧
public class LinkedNode {
public int data;
public LinkedNode next = null;
}
class LinkedList {
private LinkedNode head = null;
// 头插法
public void addFirst(int data) {
LinkedNode node = new LinkedNode();
node.data = data;
if (this.head == null) {
this.head = node;
return;
}
node.next = head;
this.head = node;
return;
}
//尾插法
public void addLast(int data) {
LinkedNode node = new LinkedNode();
node.data = data;
if (this.head == null) {
this.head = node;
return;
}
//需要先找到最后一个节点
LinkedNode cur = this.head;
while (cur.next != null) {
cur = cur.next;
}
cur.next = node;
}
//打印所有元素
public void display() {
System.out.print("[");
for (LinkedNode node = this.head; node != null; node = node.next) {
System.out.print(node.data);
if (node.next != null) {
System.out.print(",");
}
}
System.out.println("]");
}
//在index后面插入data
public void addIndex(int index, int data) {
if (index < 0 || index > size()) {
return;
}
if (index == 0) {
addFirst(data);
return;
}
if (index == size()) {
addLast(data);
return;
}
LinkedNode node = new LinkedNode();
node.data = data;
//找到index位置节点的前一个节点pre
LinkedNode pre = getIndexpos(index - 1);
node.next = pre.next;
pre.next = node;
}
public LinkedNode getIndexpos(int index) {
LinkedNode cur = this.head;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
return cur;
}
//求链表长度
public int size() {
int size = 0;
for (LinkedNode node = this.head; node != null; node = node.next) {
size++;
}
return size;
}
//查找是否包含关键字key是否在单链表当中
public boolean contanins(int key) {
//遍历链表
for (LinkedNode cur = this.head; cur != null; cur = cur.next) {
if (cur.data == key) {
return true;
}
}
return false;
}
//删除第一次出现关键字为key的节点
public void remove(int toRemove) {
//删除元素核心是得找到目标元素的前一个位置
//先判断空链表情况
if (head == null) {
return;
}
//先考虑是不是头结点
if (head.data == toRemove) {
this.head = this.head.next;
return;
}
//删除中间节点,找到要删除元素的前一个元素
LinkedNode pre = searchPre(toRemove);
if (pre != null) {
pre.next = pre.next.next;
} else {
System.out.println("没有这个数据");
return;
}
}
//删除链表中所有出现的这个数
public void removeAll(int toRemove) {
if (head == null) {
return;
}
while (searchPre(toRemove) != null) {
remove(toRemove);
}
}
//查找链表中的一个数
private LinkedNode searchPre(int toRemove) {
LinkedNode prev = this.head;
while (prev.next != null) {
if (prev.next.data == toRemove) {
return prev;
}
prev = prev.next;
}
return null;//表示没找到
}
//清空链表
public void clear() {
head = null;
}
}
这是测试代码
public class TestLinkedList {
public static void main(String[] args) {
testaddFirst();
testaddLast();
testaddIndex();
testRemove();
testContains();
testRemoveAll();
testClear();
}
public static void testaddFirst(){
System.out.println("头插法");
LinkedList list=new LinkedList();
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
list.addFirst(4);
list.display();
System.out.println("长度为"+list.size());
System.out.println();
}
public static void testaddLast(){
System.out.println("尾插法");
LinkedList list = new LinkedList();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.display();
System.out.println("长度为"+list.size());
System.out.println();
}
public static void testaddIndex(){
System.out.println("在2的后面插入5");
LinkedList list=new LinkedList();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.getIndexpos(1);
list.display();
list.addIndex(2,5);
list.display();
System.out.println();
}
public static void testRemove(){
System.out.println("删除第2个节点");
LinkedList list=new LinkedList();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.display();
list.remove(2);
list.display();
System.out.println();
}
public static void testContains(){
System.out.println("判断5是否在链表中");
LinkedList list=new LinkedList();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
System.out.println(list.contanins(5));
list.display();
System.out.println();
}
public static void testRemoveAll(){
System.out.println("删除全部为4的");
LinkedList list=new LinkedList();
list.addFirst(4);
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
list.addFirst(4);
list.addFirst(4);
list.addFirst(4);
list.addFirst(4);
list.display();
list.removeAll(4);
list.display();
System.out.println();
}
public static void testClear(){
System.out.println("清空链表");
LinkedList list=new LinkedList();
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
list.addFirst(4);
list.display();
list.clear();
list.display();
}
}
当然啦成果还是要展示一下的
以上就是小白我写的一个简单的单链表啦,可能不是很完美,要是哪里可以改进什么的,欢迎大佬们给我指点呀,谢谢大家啦。