链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。
最近学习了Java数据结构中的单链表,为了提高下自己的代码能力以及对单链表的理解,于是手动实现部分单链表的操作。
1. 创建单链表
2. 打印单链表
3. 找到倒数第一个节点
4. 链表的长度
5. 找到倒数第二个节点
6. 找到第n个节点(n从1开始)
7. 是否包含关键字key节点
8. 头插法
9. 尾插法
10. 找到index-1位置的节点
11. 在任意位置插入data节点
12. 找到关键字key的节点
13. 删除第一个出现key的节点
14. 删除所有key节点
15. 清空一个单链表
16. 反转一个单链表
17. 返回中间链表,如果有两个中间节点,返回第二个
MyLinkedList
class Node {
public int val;
public Node next;
public Node() {
}
public Node(int val) {
this.val = val;
}
}
public class MyLinkedList {
public Node head;//表示当前链表的头 默认是null
//创建单链表
public void createLinked() {
this.head = new Node(12);
Node node2 = new Node(22);
Node node3 = new Node(32);
Node node4 = new Node(42);
this.head.next = node2;
node2.next = node3;
node3.next = node4;
}
//打印单链表
public void display() {
Node cur = this.head;
while (cur != null) {
System.out.print (cur.val +" ");
cur = cur.next;
}
System.out.println();
}
//找到倒数第一个节点
public Node findLastNode() {
if(this.head == null) {
System.out.println("head == null");
return null;
}
Node cur = this.head;
while (cur.next != null) {
cur = cur.next;
}
return cur;
}
//链表的长度
public int size() {
Node cur = this.head;
int count = 0;
while(cur != null) {
count++;
cur = cur.next;
}
return count;
}
//找到倒数第二个节点
public Node findLastTwoNode() {
if(this.head == null) {
System.out.println("链表为空!");
return null;
}
if(this.head.next == null) {
System.out.println("只有一个节点!");
return null;
}
Node cur = this.head;
while(cur.next.next != null) {
cur = cur.next;
}
return cur;
}
//找到第n个节点(n从1开始)
public Node findN(int n) {
if(this.head == null) {
System.out.println("链表为空!");
return null;
}
if(n <= 0) {
System.out.println("n太小了!");
return null;
}
if(n > size()) {
System.out.println("n太大了!");
}
int count = 1;
Node cur = this.head;
while(count != n) {
count++;
cur = cur.next;
}
return cur;
}
//是否包含关键字key节点
public boolean contains(int key) {
Node cur = this.head;
while(cur != null) {
if(cur.val == key) {
return true;
}
cur = cur.next;
}
return false;
}
//头插法
public void addFirst(int data) {
Node node = new Node(data);
if(this.head == null){
this.head = node;
}else{
node.next = this.head;
this.head = node;
}
}
//尾插法
public void addLast(int data) {
Node node = new Node(data);
if(this.head == null) {
this.head = node;
}else{
Node cur = this.head;
while(cur.next != null) {
cur = cur.next;
}
cur.next = node;
}
}
//找到index-1位置的节点
public Node moveIndex(int index) {
Node cur = this.head;
int count = 0;
while(count != index-1) {
cur = cur.next;
count++;
}
return cur;
}
//在任意位置插入data节点
public void addIndex(int index,int data) {
if(index < 0 || index >size()) {
System.out.println("index不合法");
return;
}
if(index == 0) {
addFirst(data);
return;
}
Node cur = moveIndex(index);
Node node= new Node(data);
node.next = cur.next;
cur.next=node;
}
//找到关键字key的节点
public Node searchPrev(int key) {
Node cur = this.head;
while(cur.next != null) {
if(cur.next.val == key) {
return cur;
}
cur = cur.next;
}
return null;
}
//删除第一个出现key的节点
public void remove(int key) {
if(this.head == null) {
return;
}
if(this.head.val == key) {
this.head = this.head.next;
}
Node prev = searchPrev(key);
if(prev == null) {
System.out.println("此前驱为空");
}else{
Node del = prev.next;
prev.next = del.next;
}
}
//删除所有key节点
public void removeAllKey(int key) {
Node prev = this.head;
Node cur = prev.next;
while(cur != null) {
if(cur.val == key) {
prev.next = cur.next;
}else{
prev = cur;
}
cur = cur.next;
}
if(this.head.val == key) {
this.head = this.head.next;
}
}
//清空一个单链表
public void clear() {
this.head = null;
}
//反转一个单链表
public Node reverseList() {
Node cur = this.head;
Node prev = null;
Node newHead = null;
while(cur != null) {
Node curNext = cur.next;
if(curNext == null) {
newHead = cur;
}
cur.next = prev;//后继变前驱
prev = cur;
cur = curNext;
}
return newHead;
}
//返回中间链表,如果有两个中间节点,返回第二个
public Node middleNode() {
Node fast = this.head;
Node slow = this.head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
TestDemo
public class TestDemo {
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addFirst(19);
myLinkedList.addFirst(29);
myLinkedList.addFirst(39);
myLinkedList.display();//39 29 19
myLinkedList.addLast(1);
myLinkedList.addLast(2);
myLinkedList.addLast(3);
myLinkedList.addLast(4);
myLinkedList.display();//39 29 19 1 2 3 4
myLinkedList.addIndex(0,110);
myLinkedList.display();//110 39 29 19 1 2 3 4
myLinkedList.addIndex(2,120);
myLinkedList.display();//110 39 120 29 19 1 2 3 4
myLinkedList.addIndex(9,119);
myLinkedList.display();//110 39 120 29 19 1 2 3 4 119
myLinkedList.addIndex(-9,119);
}
public static void main2(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
//这个函数结束之后,我们拿到了当前链表的头节点
myLinkedList.createLinked();
myLinkedList.display();
System.out.println("==================");
int n = 4;
Node ret = myLinkedList.findN(n);
System.out.println("第"+n+"个节点是:"+ret.val);
System.out.println("==================");
System.out.println(myLinkedList.size());
System.out.println("==================");
System.out.println(myLinkedList.contains(421));
}
public static void main1(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
//这个函数结束之后,我们拿到了当前链表的头节点
myLinkedList.createLinked();
myLinkedList.display();
System.out.println("==================");
try {
//放的是可能出现异常代码
Node ret = myLinkedList.findLastTwoNode();
System.out.println(ret.val);
}catch (NullPointerException e) {
}
System.out.println("==================");
/*ret = myLinkedList.findLastTwoNode();
System.out.println(ret.val);*/
System.out.println("虽然发生了异常,但是我还是想打印这句话");
}
}
测试结果
39 29 19
39 29 19 1 2 3 4
110 39 29 19 1 2 3 4
110 39 120 29 19 1 2 3 4
110 39 120 29 19 1 2 3 4 119
index不合法