【算法day6】哈希表、有序表、链表(反转单链表)
哈希表的简单介绍
1)哈希表在使用层面上可以理解为一种集合结构
2)如果只有key,没有伴随数据value,可以使用HashSet结构(C++中叫UnOrderedSet)
3)如果既有key,又有伴随数据value,可以使用HashMap结构(C++中叫UnOrderedMap)
4)有无伴随数据,是HashMap和HashSet唯一的区别,底层的实际结构是一回事
5)使用哈希表增(put)、删(remove)、改(put)和查(get)的操作,可以认为时间复杂度为O(1)(常数级别),但是常数时间比较大
6)放入哈希表的东西,如果是基础类型,内部按值传递,内存占用就是这个东西的大小
7)放入哈希表的东西,如果不是基础类型,内部按引用传递,内存占用是这个东西内存地址的大小
有序表的简单介绍
1)有序表在使用层面上可以理解为一种集合结构
2)如果只有key,没有伴随数据value,可以使用TreeSet结构(C++中叫OrderedSet)
3)如果既有key,又有伴随数据value,可以使用TreeMap结构(C++中叫OrderedMap)
4)有无伴随数据,是TreeSet和TreeMap唯一的区别,底层的实际结构是一回事
5)有序表和哈希表的区别是,有序表把key按照顺序组织起来,而哈希表完全不组织
6)红黑树、AVL树、size-balance-tree和跳表等都属于有序表结构,只是底层具体实现不同
7)放入有序表的东西,如果是基础类型,内部按值传递,内存占用就是这个东西的大小
8)放入有序表的东西,如果不是基础类型,必须提供比较器,内部按引用传递,内存占用是这个东西内存地址的大小
9)不管是什么底层具体实现,只要是有序表,都有以下固定的基本功能和固定的时间复杂度
有序表的固定操作
void put(K key,V value):将一个(key,value)记录加入到表中,或者将key的记录更新成value。
v get(k key):根据给定的key,查询value并返回。3) void remove(K key):移除key的记录。
boolean containsKey(K key):询问是否有关于key的记录。
K firstKey():返回所有键值的排序结果中,最左(最小)的那个。6)K lastKey():返回所有键值的排序结果中,最右(最大)的那个。
K floorKey (K key):如果表中存入过key,返回key;否则返回所有键值的排序结果中,,,key的前一个。
K ceilingKey (K key):如果表中存入过key,返回key;否则返回所有键值的排序结果中,key的后一个。
以上所有操作时间复杂度都是0(logN),N为有序表含有的记录数
链表
链表知识学习:https://blog.csdn.net/m0_57950108/article/details/121639962
java知识回忆:https://www.liaoxuefeng.com/wiki/1252599548343744/1260454185794944
单向链表反转
假设有以下链表
1→2→3→null
需要返回的链表是
3→2→1→null
怎么做?
一般有两种做法
方法一:使用一个中间变量保存下一节点指针
视频讲解:https://www.bilibili.com/video/BV1KZ4y157Up/?spm_id_from=333.788
单链表的每个节点都只存了它的下一节点的地址指针
因此,设三个变量
pre:代表指向当前节点上一个节点的指针
cur:代表指向当前节点的指针
tmp:用于保存指向当前节点下一个节点的指针
public class LinkNode ReverseList {
# 定义一个单链表
public static class Node {
public int value; //节点储存的值
public Node next; //节点储存的下一节点的地址指针
public Node(int data) {
this.value = data;
}
}
# 创建一个单链表反转方法
public static Node reverseList(Node head) {
Node pre = null; //指向当前节点的前一个节点的指针
Node cur = head; //指向当前节点的指针
Node tmp; //用于保存当前节点的下一节点,防止链表断掉
while (cur != null) {
//先将当前节点的后一个节点的地址保存
tmp = cur.next;
//将当前节点的后一个节点指针指向当前节点的前一个节点
cur.next = pre;
//将pre指向当前节点位置
pre = cur;
//将当前节点位置后移
//此时已经是2-1-3了
cur = tmp;
}
//等pre指到链表尾部(null)时结束并返回前一个值
//此时链表变为3-2-1
return pre;
}
public static void printLinkedList(Node head) {
System.out.print("Linked List: ");
while (head != null) {
System.out.print(head.value + " ");
head = head.next;
}
System.out.println();
}
public static void main(String[] args) {
Node head1 = new Node(1);
head1.next = new Node(2);
head1.next.next = new Node(3);
printLinkedList(head1);
head1 = reverseList(head1);
printLinkedList(head1);
}
}
方法二:不使用中间变量(via左神)
public class LinkNode ReverseList {
# 定义一个单链表
public static class Node {
public int value; //节点储存的值
public Node next; //节点储存的下一节点的地址指针
public Node(int data) {
this.value = data;
}
}
# 创建一个单链表反转方法
public static Node reverseList(Node head) {
Node pre = null; //指向当前节点的前一个节点的指针
Node next = null; //指向当前节点的后一个节点的指针
//若头结点不为空
while (head != null) {
//先将头结点的后一个节点的地址保存
next = head.next;
//将头结点的后一个节点指针指向头结点的前一个节点
head.next = pre;
//将pre指向当前节点(头结点)位置
pre = head;
//将当前节点位置后移,移动到下一个数
//此时已经是2-1-3了
head = next;
}
//等pre指到链表尾部(null)时结束并返回前一个值
//此时链表变为3-2-1
return pre;
}
public static void printLinkedList(Node head) {
System.out.print("Linked List: ");
while (head != null) {
System.out.print(head.value + " ");
head = head.next;
}
System.out.println();
}
public static void main(String[] args) {
Node head1 = new Node(1);
head1.next = new Node(2);
head1.next.next = new Node(3);
printLinkedList(head1);
head1 = reverseList(head1);
printLinkedList(head1);
}
}
【算法day6】哈希表、有序表、链表(反转单链表)的更多相关文章
- Reverse反转算法+斐波那契数列递归+Reverse反转单链表算法--C++实现
Reverse反转算法 #include <iostream> using namespace std; //交换的函数 void replaced(int &a,int & ...
- 特殊的反转单链表算法(C++)
普通的单链表反转算法 大学的时候也做过好几次单链表的反转,记得当时都是用三个变量不断修改next的值然后实现反转. ListNode* reverseList(ListNode* head) { Li ...
- [算法][LeetCode]Linked List Cycle & Linked List Cycle II——单链表中的环
题目要求 Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up: Can you so ...
- [C++]线性链表之单链表
[文档整理系列] 线性链表之单链表 /* 问题描述:线性表____链表_____单链表 @date 2017-3-7 */ #include<iostream> using namespa ...
- 数据结构5: 链表(单链表)的基本操作及C语言实现
逻辑结构上一个挨一个的数据,在实际存储时,并没有像顺序表那样也相互紧挨着.恰恰相反,数据随机分布在内存中的各个位置,这种存储结构称为线性表的链式存储. 由于分散存储,为了能够体现出数据元素之间的逻辑关 ...
- 【数据结构】单链表介绍及leetcode206题反转单链表python实现
题目传送门:https://leetcode-cn.com/problems/reverse-linked-list/ 文章目录 单链表介绍 链表 概念 种类 优缺点 单链表(slist) leetc ...
- 在O(n) 时间复杂度,O(1)空间复杂度内反转单链表
在LeetCode中看到判断回文的程序:https://leetcode.com/problems/palindrome-linked-list/ 里面用单链表来存储数据,先反转前半部分的单链表,然后 ...
- 以K个为一组反转单链表,最后不足K个节点的部分也反转
package StackMin.ReverseList_offer16; public class ReverseKgroup_extend_offer16 { /** * 分组反转单链表,最后不足 ...
- java练习题:用递归反转单链表
问题:用递归反转单链表. 单链表结构: class ListNode{ int val; ListNode next; ListNode(int value){ this.val=value; }} ...
- 查找(顺序表&有序表)
[1]查找概论 查找表是由同一类型是数据元素(或记录)构成的集合. 关键字是数据元素中某个数据项的值,又称为键值. 若此关键字可以唯一标识一个记录,则称此关键字为主关键字. 查找就是根据给定的某个值, ...
随机推荐
- 一个简单的监控java进程获取日志的办法
公司里面一个长时间运行的环境会出现问题, 这边简单写了一个脚本自动获取日志信息 脚本如下 注意 我的path 其实就是复用的 我们应用里面的jdk 剩下的就非常简单了. 每个日志都自动打包 并且移除 ...
- 使用Grafana 监控 SQLSERVER数据库
使用Grafana 监控 SQLSERVER数据库 1.获取镜像信息以及启动镜像 docker pull awaragi/prometheus-mssql-exporter docker run -e ...
- 【行云流水线】满足你对工作流编排的一切幻想~skr
流水线模型 众所周知,DevOps流水线(DevOps pipeline)的本质是实现自动化工作流程,用于支持软件开发.测试和部署的连续集成.交付和部署(CI/CD)实践.它是DevOps方法论的核心 ...
- Spring Boot日志框架Slf4j+logback
一.简介 Slf4j Java的简单日志记录外观(Simple Logging Facade for Java )可作为各种日志记录框架(例如java.util.logging,logback,log ...
- echarts显示地图
<template> <div class="managingPatientSize"> <div id="china-map"& ...
- IDM(最佳的Windows下载工具)
如果你是一名互联网"老司机",那么一定听过「IDM」这款下载工具的大名!它的全名叫做 Internet Download Manager (互联网下载管理器),缩写就是 IDM. ...
- 【Spring】Bean装配类注解
默认注入类型 多个同类型Bean 注入失败 依赖 使用目标(@Target) @AutoWired 通过type 默认首先安装属性名称进行注入 结合@Qualifier注解(value属性)设置注入的 ...
- Centos7 本地与网络Yum源配置
虽然Yum工具,只需要你的主机连接互联网,就可以直接使用,但是有些时候我们需要自定义Yum源实现加速,下面我们将配置一个本地Yum源,来使用光盘中的软件,其他网络配置操作步骤相同,只是会在baseur ...
- 从此告别涂硅脂 利民推出新款CPU固态导热硅脂片:一片26.9元
利民(Thermalright)近日推出了新款Heilos CPU固态导热硅脂片,其中Intel版为26.9元,AMD版售价29.9元. 以往向CPU上涂硅脂,需要先挤一粒绿豆大小的硅脂,然后用塑料片 ...
- DevToys(开发工具) v1.0.2.1
从事开发工作的朋友们千万不要错过了!今天为大家带来的这款软件可以说是开发人员的必备工具,它就是DevToys软件!DevToys中包含了许多强大实用的开发工具,能够帮助用户将程序开发变得更加简单大大降 ...