系统开始学后端

几类常见的数据结构(哈希表,栈,队列)的简单了解

2019-02-09  本文已影响0人  DeeJay_Y

时间空间复杂度

要理解不同时间复杂度相对于数据量的增长速度是不一样的。

  1. 数有多少个循环嵌套,大概可以知道是平方立方还是更高的次方
  2. 如果有“二分”这样的结构,一般会包括logn
  3. 可以数一下搜索空间确定复杂度

哈希表

基本性质

类似于数组,可以使用数组的下标索引去访问存储的数据,哈希表也一样,可以通过Key去访问对应的Value。不同于数组的是,数组下标只能为数字,而哈希表Key可以是任意类型。

即,哈希表支持增删改查4种操作。
对于哈希表的增删改查,其时间复杂度都近似为O(1), 并且不依赖于插入的顺序,即随机访问(想访问哪个数据就马上访问哪个数据)
哈希表中的数据没有顺序,所以也不可以对哈希表进行排序!

哈希表和数组的不同点对比
  • 数组下标为数字,而哈希表可以支持更多的数据类型
  • 数组在中间插入数据的时候,时间复杂度一般不是O(1)

基本使用

代码举例:

import java.util.HashMap;

public class Main {

    public static void main(String[] args) {
//        HashMap即为哈希表实现的一个数据结构类
        HashMap<String, String> hashmap = new HashMap<String, String >(); // 声明一个哈希表数据结构

//        增加操作
        hashmap.put("Name", "Yang"); // 增
        hashmap.put("Gender", "Male"); // 增
//        查询操作
        if(hashmap.containsKey("Name")) {
            System.out.println(hashmap.get("Name")); // Yang
        }
//        对于查询操作,如果Key不存在,get方法会返回null,也可以通过这个来判断
//        String value = hashmap.get("Name");
//        if(value != null) {
//            System.out.println(value);
//        }
//        修改操作 和 新增操作一样  会覆盖同样的Key值
        hashmap.put("Gender", "Female"); // 覆盖掉
        System.out.println(hashmap.get("Gender")); // Female
//        删除 remove
        hashmap.remove("Gender");
        System.out.println(hashmap.get("Gender")); // null
    }


}

基本实现原理

基本实现思路为把任意的Key值转换为数字,然后作为数组的下标,然后把Value存储在数组下标对应位置上。

ValueClass[] array = new ValueClass[size];

比如:

  1. 修改操作:
String key = someString();
int index = hash(key); // 找到哈希表对应的Key对应的数字下标
array[index] = value;

2.访问操作

int index = hash(key);
ValueClass value = array[index];

一个数据结构,用于存储数据,支持2种操作:

所有操作的时间复杂度均为O(1)

跟哈希表不同的是,哈希表可以随机访问,但是栈对数据访问顺序做了限制,先进后出,后进先出,即访问的话只能访问到最近放进栈里的那个数据

函数调用栈

假设现有如下函数

function f1() {
    f2();
    someCode...
}
function f2() {
    f3();
    someCode...
}

调用f1时,会将此时f1的状态压入栈中,然后调用f2,再将f2此时的状态压入栈中,再去调用f3(),f3()调用完成后再从栈中取出f2的状态继续执行,执行完后再次从栈中取出f1的状态继续执行。

基本使用

import java.util.Stack;

public class Main {

    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<Integer>();
        stack.push(3); // 增
        stack.push(5); // 增
        
        System.out.println(stack.pop()); // 5
        System.out.println(stack.pop()); // 3
    }

}
栈的额外操作
  • 使用peek()可以查看栈顶端的数据同时又不删除该数据
  • 使用empty()可以查看栈是否为空

队列

一个类似于栈的数据结构,用于存储数据,同样支持2种操作

所有操作的时间复杂度均为O(1)

队列遵循一个先进先出,后进后出的顺序,即在队列中取出数据的顺序和放进去的顺序是一样的。

队列使用举例
public class Main {

    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<Integer>();

        queue.add(3);
        queue.add(5);

        System.out.println(queue.peek()); // 3

        System.out.println(queue.poll()); // 3
        System.out.println(queue.poll()); // 5

        System.out.println(queue.isEmpty()); // true
    }

}
上一篇 下一篇

猜你喜欢

热点阅读