java —— 链表

java —— 链表

一、单向链表

(一)链表代码部分

  1. 链表的实现部分
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. 链表部分
// 单向链表
/*
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}

(二)链表的插入、修改、删除

  1. 插入(运用插入可以使链表有序排列
// 将其加入指定位置
    // 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;
        }
    }
  1. 修改
 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");
    }
  1. 删除(单向链表不可以进行自我删除
  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();
 

二、双向链表

(一)链表代码部分

  1. 链表部分:
// 创建一个双向链表的类
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指向了最后一个节点,再将此指向新的节点
    }

(二)插入、修改、删除

  1. 插入
双向链表和单向链表一致
  1. 修改
// 双向链表的修改和单项链表一致
    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()+"}";
    }
}

  1. 删除(双向链表可以进行自我删除
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()+"}";
    }
}


END

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页