java —— 链表
一、单向链表
(一)链表代码部分
- 链表的实现部分
import java.util.Scanner;
public class ListDemo {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
List list = new List();
for (int i = 0; i < n; i ++){
Character per = new Character();
String str = sc.next();
String scr = sc.next();
int num = sc.nextInt();
per.setName(str);
per.setAbility(scr);
per.setAge(num);
list.addCharacter(per); // 插入链表中
}
list.printList();
}
}
- 链表部分
// 单向链表
/*
1. 找到当前链表的最后节点
2. 将最后节点的next 指向下一个节点
*/
class List {
// 先初始化一个头节点,头节点一般不要移动
private Character head = new Character(); // 一般不存放具体数据
public void addCharacter(Character person) {
Character temp = head;
while (true) { // 遍历链表,找到链表的最后一个节点
if (temp.next == null)
break;
else // 否则就把temp移向下一个节点
temp = temp.next;
}
temp.next = person; // 退出循环则代表temp的next指向了最后一个节点,再将此指向新的节点
}
// 利用遍历显示链表
public void printList() {
Character temp = head.next;
while (true) {
if (temp == null)
break;
else {
System.out.println(temp);
temp = temp.next;
}
}
}
}
// 定义Character,每一个Character对象就是一个节点
class Character {
String name;
String ability;
int age;
Character next; // 指向下一个结点
// 构造方法
public Character() {
}
public Character(String name, String ability, int age) {
this.name = name;
this.ability = ability;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAbility() {
return ability;
}
public void setAbility(String ability) {
this.ability = ability;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Character getNext() {
return next;
}
public void setNext(Character next) {
this.next = next;
}
@Override
public String toString() {
return "Character{" +
"name='" + name + '\'' +
", ability='" + ability + '\'' +
", age=" + age +
'}';
}
}
结果如下:
Character{name='太宰治', ability='人间失格', age=22}
Character{name='中原中也', ability='污浊了的忧伤之中', age=22}
(二)链表的插入、修改、删除
- 插入(运用插入可以使链表有序排列)
// 将其加入指定位置
// temp 是位于添加位置的前一个节点
public void insertList(Character person) { // 插入
Character temp = head;
boolean flag = false; // 判断链表中是否存在相同的标号
while (true) {
if (temp.next == null)
break; // 说明temp已经在链表的最后了
else if (temp.next.nume > person.nume) //位置已经找到,就在temp的后面将其插入
break;
else if (temp.next.nume < person.nume)
temp = temp.next;
else{
flag = true; // 说明编号存在
break;
}
}
// 判断 flag 的值
if (flag){
System.out.println("此人物标号重复");
}else{
person.next = temp.next;
temp.next = person;
}
}
- 修改
public void resiveList(Character person) { // 修改
if (head.next == null) // 判断链表是否为空
System.out.println("null");
Character temp = head.next;
boolean flag = false; // 设置flag来进行后面的判断
while (true){
if (temp == null)
break; // 说明已经遍历完
if (temp.nume == person.nume){ // 这说明找到了需要修改的位置
flag = true; // 将flag赋予true
break;
}else temp = temp.next;
}
if (flag) { // 当flag为true进行修改操作
temp.name = person.name;
temp.age = person.age;
temp.ability = person.ability;
}else System.out.println("error");
}
- 删除(单向链表不可以进行自我删除)
public void deleteList(int nume) { // 删除:直接让要被删除部分的前一个节点指向被删除部分的下一个节点
if (head.next == null) // 判断链表是否为空
System.out.println("error");
Character temp = head.next;
boolean flag = false;
while (true) {
if (temp.next == null)
break;
if (temp.next.nume == nume){ // 找到了需要删除的地方
flag = true;
break;
}else temp = temp.next;
}
if (flag) {
temp = temp.next.next;
}else System.out.println("error");
}
}
注: 可以通过 插入法对链表进行排序,将上述实现部分的for处改为如下:
for (int i = 0; i < n; i ++){
Character per = new Character();
String name = sc.next();
String ability = sc.next();
int age = sc.nextInt();
int num = sc.nextInt();
per.setName(name);
per.setAbility(ability);
per.setAge(age);
per.setNume(num);
list.insertList(per);
}
list.printList();
二、双向链表
(一)链表代码部分
- 链表部分:
// 创建一个双向链表的类
class Person {
String name;
int nume;
Person next; // 指向下一个结点
Person pre; // 指向上一个节点
// 构造方法
public Person() {
}
public Person(String name, int nume) {
this.name = name;
this.nume = nume;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNume() {
return nume;
}
public void setNume(int nume) {
this.nume = nume;
}
public Person getNext() {
return next;
}
public void setNext(Person next) {
this.next = next;
}
public Person getPre() {
return pre;
}
public void setPre(Person pre) {
this.pre = pre;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", nume=" + nume +
'}';
}
}
// 双向链表
class DoubleList {
private Person head = new Person(); //
public void printDoubleList() {
Person temp = head.next;
while (true) {
if (temp == null)
break;
else {
System.out.println(temp);
temp = temp.next;
}
}
}
// 增加只需要加入一个上一个节点即可
public void addPerson(Person person) {
Person temp = head;
while (true) { // 遍历链表,找到链表的最后一个节点
if (temp.next == null)
break;
else // 否则就把temp移向下一个节点
temp = temp.next;
}
// 形成双向链表
person.pre = temp;
temp.next = person; // 退出循环则代表temp的next指向了最后一个节点,再将此指向新的节点
}
(二)插入、修改、删除
- 插入
双向链表和单向链表一致
- 修改
// 双向链表的修改和单项链表一致
public void resiveDoubleList(Person person) {
if (head.next == null) // 判断链表是否为空
System.out.println("null");
Person temp = head.next;
boolean flag = false;
while (true) {
if (temp == null)
break; // 说明已经遍历完
if (temp.nume == person.nume) {
flag = true;
break;
} else temp = temp.next;
}
if (flag) {
temp.name = person.name;
} else System.out.println("error");
}
三、链表(提供者:Jplusztc)
class Node{
int data;
Node next;
public Node() {}
public Node(int data, Node next) {
this.data = data;
this.next = next;
}
}
//带头结点的链表
public class LinkedList {
private Node head;
private int size;
public LinkedList() {
this(false);
}
public LinkedList(boolean ascend, int...arr){
head = new Node();
size = 0;
addBySort(ascend, arr);
}
public int size(){
return this.size;
}
public boolean isEmpty(){return this.size == 0;}
//需要学会的方法,将添加进链表的数据均按顺序排列
//ascend为true代表是升序,否则为降序
//注意这里是private, 我只对创建链表时传入的数据进行排序
private void addBySort(boolean ascend, int...arr){
for (int i = 0; i < arr.length; i++) {
int num = arr[i];
Node temp = head;
while (temp != null){
if (temp.next == null){
temp.next = new Node(num, null);
break;
}
if (ascend){
if (temp.next.data > num) {
temp.next = new Node(num, temp.next);
break;
}
}else {
if (temp.next.data < num) {
temp.next = new Node(num, temp.next);
break;
}
}
temp = temp.next;
}
size++;
}
}
//添加到末尾
public void add(int data){
add(data, size);
}
//添加到链表指定下标处
public void add(int data, int index){
if (index < 0 || index > size){
throw new IndexOutOfBoundsException("下标越界");
}
Node temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
temp.next = new Node(data, temp.next);
size++;
}
//删除指定下标处的数据, 下标范围[0, size)
public void delete(int index){
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("下标越界");
Node temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
temp.next = temp.next.next;
size--;
}
//删除遇到的data, deleteAll为True时,删除所有的data,否则只删除第一个
public void deleteData(int data, boolean deleteAll){
Node temp = head;
while (temp.next != null){
if (temp.next.data == data){
temp.next = temp.next.next;
size--;
if (!deleteAll) break;
}
temp = temp.next;
}
}
@Override // 方法重写
public String toString() {
Node temp = head.next;
StringBuilder s = new StringBuilder();
while (temp != null){
s.append(temp.data);
temp = temp.next;
if (temp != null) s.append(", ");
}
return "LinkedList{"+s.toString()+"}";
}
}
- 删除(双向链表可以进行自我删除)
class Node{
int data;
Node next;
public Node() {}
public Node(int data, Node next) {
this.data = data;
this.next = next;
}
}
//带头结点的链表
public class LinkedList {
private Node head;
private int size;
public LinkedList() {
this(false);
}
public LinkedList(boolean ascend, int...arr){
head = new Node();
size = 0;
addBySort(ascend, arr);
}
public int size(){
return this.size;
}
public boolean isEmpty(){return this.size == 0;}
//需要学会的方法,将添加进链表的数据均按顺序排列
//ascend为true代表是升序,否则为降序
//注意这里是private, 我只对创建链表时传入的数据进行排序
private void addBySort(boolean ascend, int...arr){
for (int i = 0; i < arr.length; i++) {
int num = arr[i];
Node temp = head;
while (temp != null){
if (temp.next == null){
temp.next = new Node(num, null);
break;
}
if (ascend){
if (temp.next.data > num) {
temp.next = new Node(num, temp.next);
break;
}
}else {
if (temp.next.data < num) {
temp.next = new Node(num, temp.next);
break;
}
}
temp = temp.next;
}
size++;
}
}
//添加到末尾
public void add(int data){
add(data, size);
}
//添加到链表指定下标处
public void add(int data, int index){
if (index < 0 || index > size){
throw new IndexOutOfBoundsException("下标越界");
}
Node temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
temp.next = new Node(data, temp.next);
size++;
}
//删除指定下标处的数据, 下标范围[0, size)
public void delete(int index){
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("下标越界");
Node temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
temp.next = temp.next.next;
size--;
}
//删除遇到的data, deleteAll为True时,删除所有的data,否则只删除第一个
public void deleteData(int data, boolean deleteAll){
Node temp = head;
while (temp.next != null){
if (temp.next.data == data){
temp.next = temp.next.next;
size--;
if (!deleteAll) break;
}
temp = temp.next;
}
}
@Override // 方法重写
public String toString() {
Node temp = head.next;
StringBuilder s = new StringBuilder();
while (temp != null){
s.append(temp.data);
temp = temp.next;
if (temp != null) s.append(", ");
}
return "LinkedList{"+s.toString()+"}";
}
}