数据结构上篇 - 线性数据结构

简介: 本篇文章属于数据结构连载篇的其中之一,共分为上中下三篇。上篇主要介绍线性数据结构数组、链表、栈、队列;中篇介绍树和图;下篇介绍复合数据结构哈希表、跳表等。希望大家持续关注,谢谢。

1 简单介绍

我们所说的数据结构主要是指数据在内存中的存储结构,即程序运行时,我们通过将数据存入不同的容器,通过操作容器内的数据,以完成我们的业务逻辑。

数据结构在物理结构上一般分为顺序结构和链式结构。

所有的数据结构,本质是不是顺序结构就是链式结构,要么就是复合结构。

  • 顺序结构(在内存中是连续的地址空间)

    image.png

  • 链式结构(在内存中是非连续的地址空间,通过存储下一个数据的地址指针(Java中就是对象变量)找到下一个数据)

    image.png

数据结构的逻辑结构,也是我们数据结构系列文章的讲解顺序,下面我仅列出大纲

  • 线性结构

    • 数组
    • 链表
    • 队列
    • 二叉树
    • 非二叉树
  • 复合数据结构

    • 哈希表
    • 跳表
    • 线段树

2 数组

数组是顺序结构的代表,也是线性结构的代表,也是日常我们最常使用的一种数据结构,Java中的ArrayList就是对数组的一种封装,使其可以动态扩容,更方便的增删改查。

image.png

访问的时间复杂度(O(1)通过下标访问,但往往需要结合搜索)

搜索的时间复杂度(O(n)可以通过二分查找优化O(logn))

插入的时间复杂度(O(n)需要移动其他元素)

删除的时间复杂度(O(n)需要移动其他元素)

特点:访问效率高,插入修改效率低,可能需要开辟比较大的连续存储空间

3 链表

链表是链式结构的代表,也是一种线性结构,Java中的LinkedList就是对链表的一种封装。

image.png

访问的时间复杂度(O(n)通过遍历访问)

搜索的时间复杂度(O(n))

插入的时间复杂度(O(1)需要修改地址指针即可)

删除的时间复杂度(O(1)需要修改地址指针即可)

特点:插入修改效率高,访问效率低,不需要连续存储空间,但是需要每个节点存放地址值,会浪费一部分空间

链表有如下几种形态

3.1 单链表

image.png

特点:访问只能向后访问,如果我们想要获取上一个节点必须再次遍历

3.2 双向链表

image.png

特点:弥补了单链表的一些不足,即可向前访问也可以向后访问,占用存储资源也更多,需要每个节点存储两个地址值

3.3 环(单向环和双向环)【严格说不属于线性结构】

image.png

image.png

特点:首尾闭合,可以用来解决一些比较有特点的问题,约瑟夫环,丢手帕问题

4 栈

栈的特点是先入后出,后入先出,也是非常经典的一种数据结构。

image.png

访问的时间复杂度(O(1)只能访问栈顶元素)

搜索的时间复杂度(O(n))

插入的时间复杂度(O(1)操作栈顶元素)

删除的时间复杂度(O(1)操作栈顶元素)

栈只有一个出入口,就像水桶一样,后进先出

Java的代码的执行原理就是借助栈来实现的,有些计算器也是基于栈来实现的

LeetCode第20题也可以巧妙的用栈来解决

package com.zhj.leetcode;

import java.util.Stack;

/**
 * 力扣 20 是否是合法括号
 * @author zhj
 */
public class Test20 {
    public static void main(String[] args) {
        String s = "()(){}[]{}";
        System.out.println(isT(s));
    }
    public static boolean isT(String s) {
        char[] chars = s.toCharArray();
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == '(' || chars[i] == '[' || chars[i] == '{') {
                stack.push(chars[i]);
            } else {
                if (stack.size() == 0) {
                    return false;
                } else {
                    Character pop = stack.pop();
                    if (chars[i] == ')') {
                        if (pop != '(') {
                            return false;
                        }
                    } else if (chars[i] == ']') {
                        if (pop != '[') {
                            return false;
                        }
                    } else if (chars[i] == '}') {
                        if (pop != '{') {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }
            }
        }
        return true;
    }
}

5 队列

队列与栈恰恰相反,队列是先进先出,两端开放(单端队列:一进一出;双端队列:两进两出)

image.png

访问的时间复杂度(O(n))

搜索的时间复杂度(O(n))

插入的时间复杂度(O(1))

删除的时间复杂度(O(1))

队列可以解决好多问题,比如上说控制超时时间删除LeetCode933

package com.zhj.leetcode;
​
import java.util.LinkedList;
import java.util.Queue;
​
/**
 * 力扣933 队列计数器
 * @author zhj
 */
public class Test933 {
    public static void main(String[] args) {
        RecentCounter rc = new RecentCounter();
        System.out.println(rc.ping(1));
        System.out.println(rc.ping(100));
        System.out.println(rc.ping(3001));
        System.out.println(rc.ping(3002));
    }
}
class RecentCounter {
    private Queue<Integer> queue;
​
    public RecentCounter() {
        queue = new LinkedList<>();
    }
​
    int ping(int t) {
        queue.add(t);
        // 计算符合3000毫秒以上出队列
        while (!queue.isEmpty() && t - queue.peek() > 3000) {
            queue.poll();
        }
        return queue.size();
    }
}
目录
相关文章
|
5月前
|
C++
数据结构01-线性结构-链表栈队列-栈篇
数据结构01-线性结构-链表栈队列-栈篇
|
5月前
【基本数据结构 三】线性数据结构:栈
【基本数据结构 三】线性数据结构:栈
51 0
|
4月前
|
存储 C语言
数据结构中的线性表链式存储介绍及其基本操作
链式存储是线性表的一种重要存储方式,它通过节点和指针的结构,实现了灵活的动态存储管理。本文介绍了单向链表的基本操作,并提供了相应的C语言代码示例。理解和掌握链表的操作对学习和应用数据结构具有重要意义。希望这篇博客能帮助你更好地理解线性表的链式存储。
114 2
|
1月前
|
存储 Java
java数据结构,线性表链式存储(单链表)的实现
文章讲解了单链表的基本概念和Java实现,包括头指针、尾节点和节点结构。提供了实现代码,包括数据结构、接口定义和具体实现类。通过测试代码演示了单链表的基本操作,如添加、删除、更新和查找元素,并总结了操作的时间复杂度。
java数据结构,线性表链式存储(单链表)的实现
|
28天前
|
机器学习/深度学习 算法 Java
[算法与数据结构] 谈谈线性查找法~
该文章详细介绍了线性查找法的基本概念与实现方法,通过Java代码示例解释了如何在一个数组中查找特定元素,并分析了该算法的时间复杂度。
|
2月前
|
存储
数据结构中的 线性结构和非线性结构
这篇文章介绍了数据结构中的线性结构和非线性结构,其中线性结构包括顺序存储结构和链式存储结构,如数组、队列、链表和栈;非线性结构包括图结构、树结构、二维数组、广义表和多维数组。
|
4月前
|
存储 算法 NoSQL
数据结构和算法——哈希查找冲突处理方法(开放地址法-线性探测、平方探测、双散列探测、再散列,分离链接法)
数据结构和算法——哈希查找冲突处理方法(开放地址法-线性探测、平方探测、双散列探测、再散列,分离链接法)
109 1
|
4月前
|
存储 算法 Java
Java数据结构与算法:线性数据结构之数组
Java数据结构与算法:线性数据结构之数组
|
5月前
|
存储 算法
【数据结构】【版本1.0】【线性时代】——顺序初现
【数据结构】【版本1.0】【线性时代】——顺序初现
【数据结构】【版本1.0】【线性时代】——顺序初现
|
5月前
|
存储
【数据结构】【版本1.1】【线性时代】——链式之力
【数据结构】【版本1.1】【线性时代】——链式之力
【数据结构】【版本1.1】【线性时代】——链式之力