目录
特点:
- 地址不连续,插入删除操作速度快
- 访问速度慢,只能从头节点开始查找
结构图:
节点类:
class Node{ //节点类
public Integer data;
public Node next;
public Node() {}
public Node(Integer data) {
this.data = data;
}
}
链表类
package com.lcb.linkedList;
public class LinkedList {
public Node head;//头指针
private Integer size;//节点个数
public LinkedList() {
this.head = new Node();
this.size = 0;
}
public Integer getSize() {
return size;
}
}
添加节点到末尾
public void add(int data) {
Node temp = head;
while(temp.next!=null) {
temp = temp.next;
}
temp.next = new Node(data);
size++;
System.out.println("添加成功");
}
插入删除
示意图:
删除第一次出现的某个数据(查找到时无法访问前一个节点的next)
- 从头节点开始查找,查找到时,把下一个节点的数据复制到本节点,然后删除下一个节点
public boolean removeByData(int key) {
Node temp = head;
while(temp.next != null) {
temp = temp.next;
if(temp.data == key) {
temp.data = temp.next.data;
temp.next = temp.next.next;
System.out.println("删除成功");
size--;
return true;
}
}
System.out.println("链表中没有该元素");
return false;
}
删除指定位置的数据
- 如果>=元素个数,直接返回
- 否则: 让要删除元素的前一个节点的next指向要删除元素后一个元素
public void removeByIndex(int index) {
if(index >= size) {
System.out.println("删除失败,下标越界!");
}else{
Node temp = head;
int count = 0;
while(temp.next != null && count<index) {
count++ ;
temp = temp.next;
}
temp.next = temp.next.next;
size-- ;
System.out.println("删除成功");
}
}
插入数据
- 如果 > 元素个数,直接返回
- 如果 = 元素个数,直接插入末尾,调用add函数即可
- 如果 < 元素个数,先获取要插入位置的前一个节点,用临时变量保存它的next指向的节点,然后把它的next指向新节点,再让新节点的next指向保存的临时变量
public void insert(int index,int data) {
if(index > size) { //大于元素个数
System.out.println("插入失败,插入的位置大于链表元素个数!");
}else if(index == size) { //插入到末尾
add(data);
}else {
int count = 0;
Node temp = head;
while(temp.next!=null && count<index) {
count++ ;
temp = temp.next;
}
Node p = temp.next;
temp.next = new Node(data,p);
size++;
System.out.println("插入成功");
}
}
查找元素
查找指定位置的元素,未查找到返回-1,查找到返回该位置元素
public int find(int index) {
if(index >= size) {
System.out.println("查找位置超过链表元素");
return -1;
}else {
Node temp = head;
int count = 0;
while(count<=index) {
count++;
temp = temp.next;
}
System.out.println("查找结果:" + temp.data);
return temp.data;
}
}
遍历列表
public void showAll() {
Node temp = head;
while(temp.next !=null) {
temp = temp.next;
System.out.print(temp.data + " ");
}
}
反转链表
创建一个新的链表头指针, 遍历原本的链表,依次把节点插入到新链表的第一个节点
public void reverse() {
if(head.next == null || head.next.next == null) {//空链表或者一个元素不需要反转
return;
}
Node current = head.next;
Node next = null;
Node newHead = new Node();
//如果当前节点不为null
while(current != null) {
//保存下一个节点的地址,便于之后改变当前地址的next时,还可以找到下一个节点
next = current.next;
//把当前节点插入到新链表的第一个元素
current.next = newHead.next;
newHead.next = current;
//继续遍历下一个元素
current = next;
}
//让原本的链表头,指向新链表的第一个元素
head.next = newHead.next;
}
验证操作:
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
LinkedList linkedList = new LinkedList();
linkedList.add(3);
linkedList.add(5);
linkedList.add(7);
boolean loop = true;
while(loop) {
System.out.println("############");
System.out.println("1.添加元素");
System.out.println("2.删除指定元素");
System.out.println("3.删除指定位置的元素");
System.out.println("4.查找指定位置的元素");
System.out.println("5.插入元素到指定位置");
System.out.println("6.显示所有");
System.out.println("0.退出");
int key = scan.nextInt();
int data = 0;
switch (key) {
case 1: System.out.println("输入要添加的数据:");
data = scan.nextInt();
linkedList.add(data);break;
case 2: System.out.println("输入要删除的元素:");
data = scan.nextInt();
linkedList.removeByData(data);break;
case 3: System.out.println("输入要删除的位置的元素:");
data = scan.nextInt();
linkedList.removeByIndex(data);break;
case 4: System.out.println("输入要查找的位置:");
data = scan.nextInt();
linkedList.find(data);break;
case 5: System.out.println("输入要插入的元素:");
data = scan.nextInt();
System.out.println("输入要插入的位置:");
int index = scan.nextInt();
linkedList.insert(index, data);;break;
case 6: linkedList.showAll();break;
case 0:loop=false;break;
default:System.out.println("无效选择");break;
}
}
}
}