数据结构(java_顺序表和链表)

顺序表在实际中的应用场景

  1. 购物清单:想象一下你去超市购物,你可以将需要购买的物品列成一张清单。这个清单就像是顺序表,物品的顺序就是它们在清单上的顺序。你可以通过清单上每个项目的位置快速找到需要的物品。

  2. 邮寄地址簿:在你的邮寄地址簿中,你可能按照字母顺序存储朋友和家人的地址。每个人的地址就像顺序表中的一个元素,你可以通过字母顺序快速找到他们的地址。

  3. 班级花名册:老师可能会用一本班级花名册来记录学生的信息,比如姓名、学号、出生日期等。这本花名册就像是一个顺序表,每个学生的信息就是顺序表中的一个元素,按照他们的出现顺序排列。

  4. 音乐播放列表:在你的手机或电脑上,你可能有一个音乐播放列表,里面按照你的喜好排列了一系列歌曲。这个播放列表就是一个顺序表,每首歌曲就是一个元素,按照它们在列表中的顺序播放。

  5. 图书馆书架:想象一下一排排整齐的书籍在图书馆的书架上。每本书就像顺序表中的一个元素,它们按照某种顺序排列,比如按照作者的姓氏首字母或者按照主题分类。

(顺序表)以学生信息为例的示例代码(类-方法-实现)

package data_structure.Sequential_List;

public class Student {
    String name;
    double score;
    int ID;

    public Student(String name, int ID, double score) {
        this.name = name;
        this.score = score;
        this.ID = ID;
    }

    public Student() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }

    @Override
    public String toString() {
        return "anme=" + name + ",ID=" + ID + ",score=" + score;
    }
}
package data_structure.Sequential_List;

public class SequentialMethod {
    //顺序表的最大存储容量为10个
    Student[] students = new Student[10];
    //记录现在的数量
    int count = 0;

    //添加元素时间复杂度O(1)
    public void add(Student student) {
        //count在允许的范围
        if (count >= 0 && count < students.length) {
            int i = count;
            students[i] = student;
            count++;
        } else {
            System.out.println("内存已满!");
        }
    }

    //查询指定元素时间复杂度O(1)
    public void search(int index) {
        if (index >= 0 && index < count) {
            System.out.println("name = " + students[index].name + ",ID = " + students[index].ID + ",score = " + students[index].score);
        } else {
            System.out.println("索引失败!");
        }
    }

    //插入指定位置和指定元素时间复杂度O(n)
    public void insert(Student student, int index) {
        if (index >= 0 && index <= count && count < students.length - 1) {
            for (int i = count; i >= index; i--) {
                students[i + 1] = students[i];
            }
            students[index] = student;
            count++;
        } else {
            System.out.println("索引错误或内存已满!");
        }
    }

    //删除指定位置的元素时间复杂度O(n)
    public void delete(int index) {
        if (index >= 0 && index <= count) {
            for (int i = index; i <= count; i++) {
                students[i] = students[i + 1];
            }
            count--;
        } else {
            System.out.println("索引失败!");
        }
    }

    //遍历所有的元素
    public void listAll(){
        for(int i=0;i<count;i++){
            Student student = students[i];
            System.out.println("name = " + student.name + ",ID = " + student.ID + ",score = " + student.score);
        }
    }
}
package data_structure.Sequential_List;

public class mainText {
    public static void main(String[] args) {
        SequentialMethod sm = new SequentialMethod();
        sm.add(new Student("jia",101,23));
        sm.add(new Student("dfs",104,343));
        sm.add(new Student("asdf",102,23442));
        System.out.println("----------------------添加元素成功----------------------------");
        sm.listAll();
        System.out.println("-------------------寻找索引为 1 的元素-------------------------");
        sm.search(1);
        System.out.println("-------------插入 1 位置和指定 aaaaaaaaaa,103,7898------------");
        sm.insert(new Student("aaaaaaaaaa",103,7898),1);
        sm.listAll();
        System.out.println("--------------------删除指定 2 索引---------------------------");
        sm.delete(2);
        sm.listAll();
    }
}

单链表在实际中的使用场景

  1. 联系人列表:在手机通讯录或电子邮件客户端中,联系人列表通常使用单链表来存储。每个联系人都可以表示为一个节点,节点中包含联系人的姓名、电话号码等信息,而指针则指向下一个联系人的节点。

  2. 任务列表:在任务管理应用程序中,任务列表可以使用单链表来组织。每个任务都是一个节点,包含任务的描述、截止日期等信息,而指针指向下一个任务节点。

  3. 浏览器历史记录:在网页浏览器中,浏览历史记录可以使用单链表来实现。每个访问的网页可以表示为一个节点,节点中包含网页的 URL、访问时间等信息,而指针则指向前一个访问的网页节点。

  4. 文本编辑器的撤销功能:在文本编辑器中,撤销功能可以使用单链表来实现。每次编辑操作会创建一个新的节点,包含编辑前后的文本内容,而指针指向上一个编辑状态的节点,以便进行撤销操作。

  5. 队列的实现:在计算机科学中,队列是一种常见的数据结构,用于存储按照先进先出(FIFO)顺序排列的元素。队列可以使用单链表来实现,其中链表的头部表示队列的前端,而尾部表示队列的后端。

  6. 循环播放列表:在音乐播放器或视频播放器中,循环播放列表可以使用单链表来实现。每个音乐或视频文件可以表示为一个节点,而指针指向下一个要播放的文件节点,最后一个节点指向列表的头部,实现循环播放。

(单链表)以学生信息为例的示例代码(类-方法-实现)

package data_structure.Single_Linked_List;

public class Stud_Node {
    String name;
    int ID;
    double score;
    Stud_Node next;

    @Override
    public String toString() {
        return name+","+ID+","+score;
    }

    public Stud_Node(String name, int ID, double score) {
        this.name = name;
        this.ID = ID;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public Stud_Node getNext() {
        return next;
    }

    public void setNext(Stud_Node next) {
        this.next = next;
    }
}
package data_structure.Single_Linked_List;
//时间复杂度都为O(n),初始化的时间复杂度为O(1)
public class SingleList_Method {
    //表头
    private Stud_Node head;
    //记录计数器
    private int count;

    //初始化链表
    public void initLinkedList() {
        head = null;
        count = 0;
    }

    //在链表尾部添加学生记录,尾插法
    public void add(Stud_Node node) {
        Stud_Node current;
        if (head == null) {
            head = node;
        } else {
            current = head;
            //找到链表的尾部
            while (current.getNext() != null) {
                current = current.getNext();
            }
            current.setNext(node);
        }
        node.setNext(null);
        count++;
    }

    //显示链表中所有学生信息
    public void listAll() {
        Stud_Node current = head;
        while (current != null) {
            System.out.println(current);
            current = current.getNext();
        }
        System.out.println("一共有" + count + "条记录!");
    }

    //根据学生ID查询学生信息并输出
    public void search(int ID) {
        Stud_Node current = head;
        //是否找到想要的数据,0未找到,1找到
        int flag = 0;
        while (current != null) {
            if (current.getID() == ID) {
                System.out.println(current);
                flag = 1;
            }
            current = current.getNext();
        }
        if (flag != 1) {
            System.out.println("未找到此学生信息!");
        }
    }

    // 删除某个学生的信息,链表为空,删除的节点是头节点,删除的节点在链表中间
    public void delete(int id) {
        if (head == null) {
            System.out.println("链表为空,删除失败!");
            return;
        }
        // 如果要删除的是头节点
        if (head.getID() == id) {
            head = head.getNext();
            count--;
            return;
        }
        Stud_Node current = head;
        Stud_Node prev = null;
        while (current != null && current.getID() != id) {
            prev = current;
            current = current.getNext();
        }
        // 如果找到了要删除的节点
        if (current != null) {
            // 删除节点在链表中间
            prev.setNext(current.getNext());
            count--;
        } else {
            System.out.println("未找到要删除的节点");
        }
    }

    //在指定的id元素后面插入新的元素
    public void insert(Stud_Node student, int id) {
        if (head == null) {
            head = student;
            System.out.println("链表为空,直接在头节点插入");
        }
        Stud_Node current = head;
        while (current != null && current.getID() != id) {
            current = current.getNext();
        }
        student.setNext(current.getNext());
        current.setNext(student);
        count++;
    }

}
package data_structure.Single_Linked_List;

public class mainText {
    public static void main(String[] args) {
        SingleList_Method sm = new SingleList_Method();
        sm.initLinkedList();
        System.out.println("---------------------------");
        //向链表中加入数据
        sm.add(new Stud_Node("jjjj",101,89.3));
        sm.add(new Stud_Node("hhhh",104,89.3));
        sm.add(new Stud_Node("rrrr",102,89.3));
        sm.listAll();
        System.out.println("---------------------------");
        //根据 ID=104 查询学生信息
        sm.search(104);
        System.out.println("---------------------------");
        //删除 ID=102 学生信息
        sm.delete(104);
        sm.listAll();
        System.out.println("---------------------------");
        sm.insert(new Stud_Node("jiahongrui",105,893),101);
        sm.listAll();
    }
}

双向链表在实际中的使用场景

  1. 浏览器历史记录:与单链表相比,双向链表更适合表示浏览器历史记录。每个页面访问都可以作为一个节点存储,节点中包含页面的信息,如URL、标题等。通过双向链表,用户可以方便地回退到之前访问的页面,而不仅仅是后退。

  2. 双向队列(Deque):双向链表可以被用作双向队列的基础数据结构。双向队列支持在队列的两端进行元素的插入和删除操作,而双向链表正是能够有效支持这种操作的数据结构。

  3. 文本编辑器的撤销与重做功能:在文本编辑器中,除了撤销功能外,还有重做功能。双向链表可以被用来实现这两种功能。每次编辑操作都会创建一个节点,用户可以通过双向链表方便地在编辑操作之间进行切换。

  4. LRU缓存算法:LRU(Least Recently Used)缓存算法中,双向链表常被用来实现LRU缓存。缓存中的每个数据项都是一个节点,当一个数据项被访问时,它被移动到链表的头部,而当缓存满时,链表尾部的数据项被移除。

  5. 文件系统中的索引结构:在文件系统中,双向链表可以被用来表示目录结构或者文件块的索引结构。每个目录或文件块可以是一个节点,节点之间通过双向指针相连,实现快速的文件查找和访问。

(双向链表)以学生信息为例的示例代码(类-方法-实现)

package data_structure.Double_Linked_list;


public class stu_Node {
    String name;
    int ID;
    double score;
    stu_Node next;
    stu_Node pre;

    @Override
    public String toString() {
        return name + "," + ID + "," + score;
    }

    public stu_Node(String name, int ID, double score) {
        this.name = name;
        this.ID = ID;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public stu_Node getNext() {
        return next;
    }

    public void setNext(stu_Node next) {
        this.next = next;
    }

    public stu_Node getPre() {
        return pre;
    }

    public void setPre(stu_Node pre) {
        this.pre = pre;
    }
}
package data_structure.Double_Linked_list;

public class Linked_Method {
    stu_Node head = null;
    stu_Node tail = null;
    private int count;
    //初始化
    public void initLinkedList() {
        head = null;
        tail = null;
        count = 0;
    }

    //尾插法
    public void add(stu_Node node){
        stu_Node current;
        //如果头节点为空
        if(head==null){
            head=node;
            tail=node;
        }else{
            current=tail;
            current.next=node;
            node.pre=current;
            tail=node;
        }
        count++;
    }

    //遍历所有元素
    public void listAll(){
        stu_Node current = head;
        while(current!=null){
            System.out.println(current);
            current=current.getNext();
        }
        System.out.println("一共有"+count+"条记录!");
    }

    //根据id寻找学生信息并显示
    public void search(int id){
        stu_Node current = head;
        int flag = 0;
        while(current!=null){
            if(current.getID()==id){
                System.out.println(current);
                flag=1;
                break;
            }
            current=current.getNext();
        }
        if(flag!=1){
            System.out.println("未找到学生信息!");
        }
    }

    //在指定的id后面添加元素
    public void insert(stu_Node student, int id) {
        if (head == null) {
            head = student;
            System.out.println("链表为空,直接在头节点插入");
            count++;
            return;
        }
        stu_Node current = head;
        // 遍历链表查找指定ID的节点
        while (current != null && current.getID() != id) {
            current = current.getNext();
        }
        // 如果找到了指定ID的节点
        if (current != null) {
            // 将新节点的下一个节点设置为当前节点的下一个节点
            student.setNext(current.getNext());
            // 将新节点的前一个节点设置为当前节点
            student.setPre(current);
            // 如果当前节点不是尾节点,则将当前节点的下一个节点的前一个节点设置为新节点
            if (current.getNext() != null) {
                current.getNext().setPre(student);
            }
            // 将当前节点的下一个节点设置为新节点
            current.setNext(student);
            count++;
        } else {
            System.out.println("未找到要插入的位置");
        }
    }
}
package data_structure.Double_Linked_list;

import data_structure.Single_Linked_List.Stud_Node;

public class mainText {
    public static void main(String[] args) {
        Linked_Method lm = new Linked_Method();
        lm.initLinkedList();
        System.out.println("---------------------------");
        //向链表中加入数据
        lm.add(new stu_Node("jjjj",101,89.3));
        lm.add(new stu_Node("hhhh",104,89.3));
        lm.add(new stu_Node("rrrr",102,89.3));
        lm.listAll();
        System.out.println("---------------------------");
        lm.search(101);
        System.out.println("---------------------------");
        lm.insert(new stu_Node("werwerwe",105,82.4),104);
        lm.listAll();
        System.out.println("---------------------------");
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值