数据结构算法前置

数据结构(一):数据结构的分类

本文主要借鉴LeetCode官方

链接:LeetCode官网图解算法数据结构

1.1 主要的数据结构类型

线性结构:有序数据元素的集合,数据元素之间的关系是一对一的关系

线性数据结构 :线性表,栈,队列,双队列,数组,串 等

非线性数据结构:各个数据元素不在保持在一个线性序列中,每个数据袁术可能与0个或多个其他数据元素发生联系

非线性数据结构:二维数组,多维数组,广义表,树(二叉树等),图等

1.2 数据类型的具体解释介绍

1.2.1 数组

数组内部的数据长度是不可变的,一旦创建就不能再进行更改长度,数组将数据存储在连续的内存空间,数组的起步是由0开始,故数据的长度是创建时的长度,但是对于索引而言,是长度减一 。

// 初始化一个数组 arr:长度为2
int[] arr = new int[2];
// 元素赋值
arr[0] = 1;
arr[1] = 2;

1.2.2 集合

可以将集合看成一个可变数组,相比较而言,可以动态的对数组进行扩容,不会有长度限制,常用的是ArrayList。

// 初始化一个arraylist集合
List<Integer> arr= new ArrayList<>();

// 向尾部添加元素
arr.add(1);
arr.add(2);
//删除元素[删除指定位置的元素,i 为索引位置]
arr.remove(1);
//用元素替代指定位置的元素[i 为索引位置,e为元素]
arr.set(i,e);

1.2.3 链表

链表是一个个节点数据连接起来得,数据结构区分为头结点,子节点,尾节点的next为null。

在这里插入图片描述

//定义一个链表节点
class ListNode {
    int val;       // 头结点
    ListNode next; // 下一个节点
    ListNode(int x) { 
    val = x;
     }
}

//节点的使用,以及值的使用
ListNode head= new ListNode (1);
ListNode next= new ListNode (2);
head.next = next;

1.2.4 栈

栈是一种先入后出的数据结构,有压栈和出栈的说法,在代码中实现常用Stack数组实现

//创建一个栈
Stack<Integer> stack = new Stack<>();
//栈的相关操作
//将元素1,2压入栈【push方法】
stack.push(1);
stack.push(2);
//元素出栈 【pop方法】
stack.pop(); //元素1出栈
stack.pop(); //元素2出栈

通常情况下,不推荐使用 Java 的 Vector 以及其子类 Stack ,而一般将 LinkedList 作为栈来使用
因为Vector是线程安全的,每个可能出现线程安全的方法上加了synchronized关键字,所以效率低。

  • Vector只能在尾部进行插入和删除操作,效率更低。

  • Vector空间满了之后,扩容是一倍,ArrayList仅仅是一半。

  • Vector分配内存的时候需要连续的存储空间,如果数据太多,容易分配内存失败。

LinkedList<Integer> stack = new LinkedList<>();

stack.addLast(1);   // 元素 1 入栈
stack.addLast(2);   // 元素 2 入栈
stack.removeLast(); // 出栈 -> 元素 2
stack.removeLast(); // 出栈 -> 元素 1

1.2.5 队列

队列是一种先入先出的数据结构,可以使用链表来进行实现需求操作

Queue<Integer> queue = new LinkedList<>();
//offer方法,将数据写入队列
queue.offer(1); // 元素 1 入队
queue.offer(2); // 元素 2 入队
queue.poll();   // 出队 -> 元素 1
queue.poll();   // 出队 -> 元素 2

1.2.6 树

树是一种非线性数据结构,节点区分为根节点和子节点,又分为左子节点和右子节点。存储的是具有“一对多”关系的数据元素的集合

结点:使用树结构存储的每一个数据元素都被称为“结点

父结点(双亲结点)、子结点和兄弟结点:对于图中的结点 A、B、C、D 来说,A 是 B、C、D 结点的父结点(也称为“双亲结点”),而 B、C、D 都是 A 结点的子结点(也称“孩子结点”)。对于 B、C、D 来说,它们都有相同的父结点,所以它们互为兄弟结点。

树根结点(简称“根结点”):每一个非空树都有且只有一个被称为根的结点

叶子结点:如果结点没有任何子结点,那么此结点称为叶子结点(叶结点)。例如图 中,结点 K、L、F、G、M、I、J 都是这棵树的叶子结点。
在这里插入图片描述
更详细请参考:树存储结构详解

//树节点的创建
class TreeNode {
    int val;        // 节点值
    TreeNode left;  // 左子节点
    TreeNode right; // 右子节点
    TreeNode(int x) { val = x; }
}

//树节点的使用和搭建树
// 初始化节点
TreeNode n1 = new TreeNode(3); // 根节点 root
TreeNode n2 = new TreeNode(4);
TreeNode n3 = new TreeNode(5);
TreeNode n4 = new TreeNode(1);
TreeNode n5 = new TreeNode(2);

// 构建引用指向
n1.left = n2;
n1.right = n3;
n2.left = n4;
n2.right = n5;

在这里插入图片描述

1.2.7 图

图是一种非线性数据结构,图可分为 有向图 和 无向图。

表示图的方法通常有两种:

邻接矩阵: 使用数组 verticesvertices 存储顶点,邻接矩阵 edgesedges 存储边; edges[i][j]edges[i][j] 代表节点 i+1 和 节点 j+1 之间是否有边。
在这里插入图片描述

int[] vertices = {1, 2, 3, 4, 5};
int[][] edges = {{0, 1, 1, 1, 1},
                 {1, 0, 0, 1, 0},
                 {1, 0, 0, 0, 1},
                 {1, 1, 0, 0, 1},
                 {1, 0, 1, 1, 0}};

邻接表: 使用数组 verticesvertices 存储顶点,邻接表 edgesedges 存储边。 edgesedges 为一个二维容器,第一维 ii 代表顶点索引,第二维 edges[i]存储此顶点对应的边集和;例如 edges[0] = [1, 2, 3, 4] 代表 vertices[0]的边集合为 [1, 2, 3, 4]。

int[] vertices = {1, 2, 3, 4, 5};
List<List<Integer>> edges = new ArrayList<>();

List<Integer> edge_1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
List<Integer> edge_2 = new ArrayList<>(Arrays.asList(0, 3));
List<Integer> edge_3 = new ArrayList<>(Arrays.asList(0, 4));
List<Integer> edge_4 = new ArrayList<>(Arrays.asList(0, 1, 4));
List<Integer> edge_5 = new ArrayList<>(Arrays.asList(0, 2, 3));
edges.add(edge_1);
edges.add(edge_2);
edges.add(edge_3);
edges.add(edge_4);
edges.add(edge_5);

1.2.8 堆

堆是一种基于「完全二叉树」的数据结构,可使用数组实现。以堆为原理的排序算法称为「堆排序」,基于堆实现的数据结构为「优先队列」。堆分为「大顶堆」和「小顶堆」,大(小)顶堆:任意节点的值不大于(小于)其父节点的值。

  • 大顶堆就是根节点最大

  • 小顶堆就是根节点最小

在这里插入图片描述

// 初始化小顶堆
Queue<Integer> heap = new PriorityQueue<>();

// 元素入堆
heap.add(1);
heap.add(4);
heap.add(2);
heap.add(6);
heap.add(8);

// 元素出堆(从小到大)
heap.poll(); // -> 1
heap.poll(); // -> 2
heap.poll(); // -> 4
heap.poll(); // -> 6
heap.poll(); // -> 8
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值