数据结构与算法[每日学习记录]

综述

数据结构包括: 数组、链表、栈、二叉树、哈希表 等等,算法对这些结构中的数据进行各种处理

  • 现实世界数据存储
  • 程序员的工具
  • 建模

数据结构特点概述

数据库优点缺点
数组插入快,如果知道下标,可以非常快的存取查找慢,删除慢,大小固定
有序数组比无序的数组查找快删除和插入慢,大小固定
提供 后进先出 方式的存取存取其他项很慢
队列提供 先进先出 方式的存取存取其他项很慢
链表插入快 删除快查找慢
二叉树查找、插入、删除都快(如果树保持平衡)删除算法 复杂
红-黑树查找 插入 删除都快 树总是平衡的算法复杂
2-3-4 树查找 插入 删除 都很快 树总是平衡的,
类似的 树 对磁盘存储有用
算法复杂
哈希表如果关键字已知 则存取极快,插入快删除慢,如果不知道关键字存取 很慢,
对存储空间使用不充分
插入 删除快 对最大数据项的存取很快对其他数据项存取慢
对 现实世界 建模有些算法慢且 复杂

抽象数据结构 (ADT)

对于大多数据结构来说,需要知晓:

  • 插入一条新的数据项
  • 寻找某一特定的数据项
  • 删除某一特定的数据项

插入 寻找 删除
还需要知道 如何迭代的访问,某一数据结构的个数据项,以便 显示 或其他操作

小结

  • 数据结构是指数据在计算机内存空间中或磁盘中的组织形式
  • 正确的选择数据结构会使程序的效率大大提高
  • 数据结构的例子由数组,栈和链表
  • 算法是完成特定任务的过程
  • 在JAVA中,算法经常通过类的方法实现

递归

  • 本质上,将原来的问题,转化为更小的同一问题

设计转换逻辑的时候,注意递归函数的"宏观"语意

递归函数就是一个函数,完成一个功能

// 计算 arr[l...n) 范围里的数字和
public static int sum(int[] arr, int l){
    if(l == arr.length)
        return 0;		// 求解最基本问题
    return arr[l] + sum(arr,l+1);	// 把原问题转化为更小的问题
}

Java 数据结构 | 菜鸟教程


Java 数据结构

Java 数据结构主要包括以下几种接口和类:

  • 枚举
  • 位集合
  • 向量
  • 字典 : 它定义了键映射到值的数据结构
  • 哈希表
  • 属性 (Properties)

Java集合框架

集合框架是一个用来代表和操纵集合的统一架构,所有的集合框架都包含如下内容:

  • 接口: 是代表集合的抽象数据类型
  • 实现(类): 是集合接口的具体实现
  • 算法: 是实现集合接口的对象里的方法执行的一些有用的计算

Set 和 List 的区别

  • Set 接口实例存储的是无序的,不重复的数据。 List 接口实例存储的是有序的,可以重复的元素
  • Set 检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>
  • List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List 长度,查找元素效率高,插入删除效率低,因为会引起其他元素位置改变<实现类有ArrayList,LinkedList,Vector>
public class runoobInterface {
    public static void main(String[] args) {

        List<String> list = new ArrayList<String>();
        list.add("Hello");
        list.add("World");
        list.add("Haaa");
        // 第一种遍历方法使用 For-each 遍历 List
        for (String str : list){
            System.out.println(str);
        }
        // 迭代器遍历
        Iterator<String> ite = list.iterator();
        while (ite.hasNext()){
            System.out.println(ite.next());
        }

        // 遍历 Map
        Map<String, String> map = new HashMap<String, String>();
        map.put("1","value1");
        map.put("2","value2");
        map.put("3","value3");
        // 通过Map.entrySet遍历key 和 value
        for (Map.Entry<String,String> entry : map.entrySet()){
            entry.getKey();  // 获取key
            entry.getValue(); // 获取Value
        }
    }
}

Java ArrayList


ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素

ArrayList 继承AbstractList 实现List 接口

package com.weirui.lesson4;

import java.util.ArrayList;

// ArrayList 是一个数组队列
public class runoobArrayList {
    public static void main(String[] args) {
        // 添加元素
        ArrayList<String> arrayList = new ArrayList<String>();
        arrayList.add("Google");
        arrayList.add("Runoob");
        arrayList.add("BaiDu");
        arrayList.add("WeiBo");
        System.out.println(arrayList);
        // 访问元素 使用get()方法
        System.out.println(arrayList.get(0));
        //访问对应下标 数组索引值从0开始

        // 修改元素 使用set() 方法
        arrayList.set(1,"WiKi");
        System.out.println(arrayList);

        //删除元素 使用remove() 方法
        arrayList.remove(3);
        System.out.println(arrayList);

        // 计算大小 使用size() 方法
        System.out.println("大小为: " + arrayList.size());

        // 迭代数组列表 使用for-each 来迭代元素
        for (String i : arrayList){
            System.out.println(i);
        }
        // ArrayList 排序  使用 sort()方法可以对字符或数字列表进行排序
    }
}

Java LinkedList


链表是一种常见的基础数据结构,是一种线性表,但是不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址

public class runoobLinkedList {
    public static void main(String[] args) {
        // 引入LinkedList 类
        LinkedList<String> linkedList = new LinkedList<String>();
        linkedList.add("Google");
        linkedList.add("Runoob");
        linkedList.add("Taobao");
        linkedList.add("Weibo");
        System.out.println(linkedList);

        // 使用 addFirst() 在头部添加元素
        linkedList.addFirst("Wiki");
        // 使用 addLast() 在尾部添加元素
        linkedList.addLast("Wiki");
        // 使用 removeFirst() 移除头部元素
        linkedList.removeFirst();
        // 使用 removeLast() 移除尾部元素
        linkedList.removeLast();
        // 使用 getFirst() 获取头部元素
        // 使用 getLast() 获取尾部元素
    }
}

Java HashSet


是一个不允许有重复元素的集合,允许有null值

Java HashMap


HashMap 是一个散列表,它存储的内容是键值对(Key - Value)映射

Map<String, String> map = Map.of("google","google.com","Runoob","Runoob.com");
Map<Integer, String> map = Map.of("1","google.com","2","Runoob.com");

// 创建一个HashMap 对象 Sites
HashMap<Integer,String> Sites = new HashMap<Integer,String>();
// 添加元素
Sites.put(1, "Google");
// 访问元素 使用 get(key) 方法来获取 key 对应的 values
Sites.get(1);
// 删除元素 使用 remove(key) 方法来删除 key 对应的键值对(key-value)
Sites.remove(1);
// 删除所有键值对 使用clear 方法
Sites.clear();
// 计算大小 使用size() 方法
// 获取 key,可以使用 keySet() 
// 通过 get(key) 获取对应的 value
// 只想获取 value,可以使用 values() 

Java Iterator (迭代器)


Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法

迭代器 it 的两个基本操作是 next,hasNext 和 remove

调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。

调用 it.hasNext() 用于检测集合中是否还有元素。

调用 it.remove() 将迭代器返回的元素删除。

Java Object


Java Object 类是所有类的父类,Java所有的类都继承了Object 子类可以使用Object 的所有方法

Java Object clone()

创建并返回一个对象的拷贝,clone方法是浅拷贝,对象内属性引用的对象只会拷贝引用地址,而不会将引用对象重新分配内存

Java 泛型


泛型是JDK5 引入的新特性,泛型提供了编译时类型安全检测机制,泛型本质是参数化类型

Java 序列化


Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。

Labuladong

数据结构种类很多,但它们存在的目的都是在不同的应用场景,尽可能高效地增删查改

线性就是 for/while 迭代为代表,非线性就是递归为代表

数组遍历框架,典型的线性迭代结构:

void traverse(int[] arr){
    for(int i = 0;i < arr.length; i++){
        //迭代访问 arr[i];
    }
}

链表遍历框架,兼具迭代和递归结构:

/* 基本的单链表节点*/
class ListNode{
    int val;
    ListNode next;
}

void traverse(ListNode head){
    for(ListNode p = head; p!= null; p = p.next){
        // 迭代访问 p.val
    }
}

void traverse(ListNode head){
    // 递归访问head.val
    traverse(head.next);
}

二叉树遍历框架,典型的非线性递归遍历结构

// 基本的二叉树节点
class TreeNode{
    int val;
    TreeNode left,right;
}
void traverse(TreeNode root){
    traverse(root.left);
    traverse(root.right);
}

二叉树和链表的递归遍历如此类似

那么对应:二叉树框架可以扩展为N叉树的遍历框架

// 基本的 N 叉树节点
class TreeNode{
    int val;
    TreeNode[] children;
}
void traverse(TreeNode root){
    for(TreeNode child : root.children){
        traverse(child);
    }
}

二叉树思路框架

void traverse(TreeNode root){
    // 前序遍历
	traverse(root.left);
    // 中序遍历
    traverse(root.right);
    // 后序遍历
}

只要涉及递归的问题,都是树的问题,很多动态规划就是在遍历一棵树

刷算法题尝试从[树]分类开始刷

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值