数据结构—学习笔记—数组、单链表

本文介绍了数据结构的基础概念,重点阐述了数组和单链表的原理、操作(如插入、删除、修改和查找)以及它们在编程中的应用。通过实例展示了如何在Java中实现链表功能。

目录

一、数据结构

1.什么是数据结构?

二、数组

三、链表

1.单链表


一、数据结构

1.什么是数据结构?

数据结构是指在计算机科学中用于存储、组织和管理数据的方式。它涉及到设计和实现数据的存储和操作方法,以便能够高效地访问和修改数据。数据结构是构建算法和程序的基础,它可以用来解决各种计算问题,并且对于不同类型的数据,可以选择不同的数据结构来最优化地处理它们。

举个栗子:就比如在图书馆存放书一样,因为书多,所以往往需要分类存放在不同的书架上,这样在找的时候就可以很快且比较准确的找到想要的书本。

常见的数据结构包括数组、链表、栈、队列、树、图等。通过了解不同数据结构的特性和应用场景,可以帮助程序员更好地设计和实现高效的算法和数据处理系统。

二、数组

数组:用于存储相同类型的多个元素。它是一个有序的元素集合,每个元素在数组中都有一个唯一的索引值,通过索引可以访问和修改特定位置的元素。

以Java为例,定义一个数组

int[]  a=new int[3]

这样我们就定义好了一个数组,并且为它获取了一个空间,这个空间又分为三个部分。

就像这样:

下面的是数组下标,格子里面就是存放数据的地方,这样就是一个数据结构了。下标就是给每个空间一个编号。

注意:数组下标是从0开始的!

数组的基本操作我这里就不赘述了,直接跳到下一个。

三、链表

链表:用于存储一系列元素。与数组不同,链表的元素在内存中不是连续存储的,而是通过指针相互连接。

1.单链表

单链表:(Singly Linked List)是一种常见的链表数据结构,它由一系列节点(Node)组成,就像这样:

定义一个Node结点:

public class ListNode {

    int val; //存储数据的地方
    ListNode next; //指向下一个结点

    public ListNode(int val) {
        this.val = val;
        this.next = null;
    }
}

链表的增删改查操作是常见的链表操作,下面是详细的操作:

  1. 插入(增)操作:

    • 在链表头部插入元素:创建一个节点,并将其指针指向链表的头节点,将新节点作为链表的新头节点。
    • 在链表尾部插入元素:创建一个节点,并将其指针指向 null,将新节点的指针赋给链表尾节点的指针。
    • 在指定位置插入元素:找到指定位置的前一个节点,创建一个新节点并将其指针指向当前前一个节点的下一个节点,然后将前一个节点的指针指向新节点,新节点的指针指向原先的后一个节点。

  2. 删除操作:

    • 删除链表头部的节点:将链表头节点的指针指向下一个节点。
    • 删除链表尾部的节点:找到倒数第二个节点,将其指针指向 null。
    • 删除指定位置的节点:找到指定位置的前一个节点,将前一个节点的指针指向被删除节点的后一个节点。
  3. 修改操作:

    • 根据指定位置修改节点的值:找到指定位置的节点,将节点的值修改为新的值。
  4. 查找操作:

    • 根据索引查找节点:从头节点开始遍历链表,直到找到指定位置的节点。
    • 根据值查找节点:从头节点开始遍历链表,直到找到匹配的值。

链表的查询操作的时间复杂度是 O(n),其中 n 是链表的长度。原因是链表的访问需要遍历整个链表。

具体代码实现:

public class ListNode {
    int val;
    ListNode next;

    public ListNode(int val) {
        this.val = val;
        this.next = null;
    }
}

public class LinkedList {
    private ListNode head;

    public LinkedList() {
        this.head = null;
    }

    // 添加节点到链表头部
    public void addToHead(int val) {
        ListNode newNode = new ListNode(val);
        newNode.next = head;
        head = newNode;
    }

    // 添加节点到链表尾部
    public void addToTail(int val) {
        ListNode newNode = new ListNode(val);

        if (head == null) {
            head = newNode;
        } else {
            ListNode curr = head;
            while (curr.next != null) {
                curr = curr.next;
            }
            curr.next = newNode;
        }
    }

    // 在指定位置插入节点
    public void insert(int val, int position) {
        if (position <= 0) {
            addToHead(val);
        } else if (position >= size()) {
            addToTail(val);
        } else {
            ListNode newNode = new ListNode(val);
            ListNode prev = head;
            for (int i = 1; i < position; i++) {
                prev = prev.next;
            }
            newNode.next = prev.next;
            prev.next = newNode;
        }
    }

    // 删除链表头部节点
    public void deleteHead() {
        if (head != null) {
            head = head.next;
        }
    }

    // 删除链表尾部节点
    public void deleteTail() {
        if (head == null || head.next == null) {
            head = null;
        } else {
            ListNode prev = head;
            ListNode curr = head.next;
            while (curr.next != null) {
                prev = curr;
                curr = curr.next;
            }
            prev.next = null;
        }
    }

    // 删除指定位置的节点
    public void delete(int position) {
        if (position < 0 || position >= size()) {
            return;
        }

        if (position == 0) {
            deleteHead();
        } else if (position == size() - 1) {
            deleteTail();
        } else {
            ListNode prev = head;
            ListNode curr = head.next;

            for (int i = 1; i < position; i++) {
                prev = curr;
                curr = curr.next;
            }

            prev.next = curr.next;
        }
    }

    // 修改指定位置节点的值
    public void update(int val, int position) {
        if (position >= 0 && position < size()) {
            ListNode curr = head;
            for (int i = 0; i < position; i++) {
                curr = curr.next;
            }
            curr.val = val;
        }
    }

    // 根据索引查找节点
    public ListNode getNode(int position) {
        if (position >= 0 && position < size()) {
            ListNode curr = head;
            for (int i = 0; i < position; i++) {
                curr = curr.next;
            }
            return curr;
        }
        return null;
    }

    // 根据值查找节点
    public ListNode search(int val) {
        ListNode curr = head;
        while (curr != null) {
            if (curr.val == val) {
                return curr;
            }
            curr = curr.next;
        }
        return null;
    }

    // 获取链表的长度
    public int size() {
        int count = 0;
        ListNode curr = head;
        while (curr != null) {
            count++;
            curr = curr.next;
        }
        return count;
    }

    // 遍历链表并打印元素
    public void printList() {
        ListNode curr = head;
        while (curr != null) {
            System.out.print(curr.val + " ");
            curr = curr.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        LinkedList list = new LinkedList();

        list.addToTail(1);
        list.addToTail(2);
        list.addToTail(3);

        list.printList();  // 输出: 1 2 3

        list.insert(4, 1);

        list.printList();  // 输出: 1 4 2 3

        list.delete(2);

        list.printList();  // 输出: 1 4 3

        list.update(5, 0);

        list.printList();  // 输出: 5 4 3

        ListNode node = list.getNode(1);
        System.out.println(node.val);  // 输出: 4

        ListNode searchResult = list.search(3);
        System.out.println(searchResult.val);  // 输出: 3
    }
}

发博客主要是为了记录学习,有问题的地方还望各位大佬指正!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值