一、链表结构

1.单向链表节点结构
public class Node{
public int value;
public Node next;
public Node(int data){
value=data;
}
}
2.双向链表节点结构
public class DoubleNode{
public int value;
public DoubleNode last;
public DoubleNode next;
public DoubleNode(int data){
value=data;
}
}
3.单向链表与双向链表最简单的练习
3.1单向链表与双链表如何反转
//单向链表反转
public static Node reverseLinkedList(Node head){
Node pre =null;
Node next = null;
while(head !=null){
next=head.next;
head.next=pre;
pre=head;
head=next;
}
//返回新的头结点
return pre;
}
//双向链表反转
public static DoubleNode reverseDoubleList(DoubleNode head){
DoubleNode pre=null;
DoubleNode next=null;
while(head!=null){
next=head.next;
head.next=pre;
head.last=next;
pre=head;
head=next;
}
//返回头结点
return pre;
}
3.2把给定值删除
//删除一个单链表中值为num的节点
public static Node removeValue(Node head,int num){
//判断头部节点需要删多少个
//如在3-3-3-3-2-2-1链表中,删掉值为3的节点,则需要删掉4个头部节点
while(head !=null){
if(head.value !=num){
break;
}
head=head.next;
}
//head来到第一个不需要删除的位置
Node pre=head;
Node cur=head; while(cur != null){
//注意:java中会自动释放无法找到的节点,不需要手动释放
if(cur.value == num){
pre.next =cur.next;
}else{
pre=cur;
}
cur= cur.next;
}
retuen pre;
}

二、栈和队列

1.逻辑概念

栈:数据先进后出

队列:数据先进先出

2.栈和队列的实际实现

双向链表实现

数组实现

1.使用双向链表实现栈和队列

(1)使用双向链表模拟栈与队列的进出操作

public static class DoubleEndsQueue<T>{
public Node<T> head;//头指针
public Node<T> tail;//尾指针
//如果从头部开始加节点采用以下方法
public void addFormHead(T value){
Node<T> cur=new Node<T>(value);
if(head==null){
head=cur;
tail=cur;
}else{
cur.next=head;
head.last=cur;
head=cur;
}
}
//如果从尾部开始加节点采用以下方式
public void addFromBottom(T value){
Node<T> cur =new Node<T>(value);
if(head ==null){
head=cur;
tail=cur;
}else{
cur.last=tail;
tail.next=cur;
tail=cur;
}
}
//从头部弹出节点
public T popFromHead(){
if(head==null){
return null;
}
Node<T> cur=head;
if(head==tail){//如果链表中只有一个节点
head=null;
tail=null;
}else{
head=head.next;
cur.next=null;
head.last=null;
}
return cur.value;
}
//从尾部弹出节点
public T popFromBottom(){
if(head==null){
return null;
}
Node<T> cur=tail;
if(head==tail){//如果链表中只有一个节点
head=null;
tail=null;
}else{
tail=tail.last;
tail.next=null;
cur.last=null;
}
return cur.value;
} }

(2)双向链表创建栈

public static class MyStack<T{
private DoubleEndsQueue<T> queue;
public MyStack(){
queue=new DoubleEndsQueue<T>();
}
//从头部插入从头部弹出,实现先进后出
//往栈中插入数据
public void push(T value){
queue.addFromHead(value);
}
//将数据弹出栈
public T pop(){
return queue.popFromHead();
}
//判断是否为空
public boolean isEmpty(){
return queue.isEmpty();
}
}

(3)双向链表创建队列

public static class MyQueue<T{
private DoubleEndsQueue<T> queue;
public MyStack(){
queue=new DoubleEndsQueue<T>();
}
//从头部插入从尾部弹出,实现先进先出
//往栈中插入数据
public void push(T value){
queue.addFromHead(value);
}
//将数据弹出栈
public T pop(){
return queue.popFromBottom();
}
//判断是否为空
public boolean isEmpty(){
return queue.isEmpty();
}
}

2.使用数组实现栈和队列

提示:只考虑固定大小数组

(1)数组实现队列:实现环形数组

public static class MyQueue{
private int[] arr;
private int pushi;//记录插入数据的位置
private int polli;//记录弹出数据的位置
private int size;//记录队列中的数据个数
private final int limit;//数组大小
//初始化数组
publish MyQueue(int limit){
arr=new int[limit];
pushi = 0;
polli=0;
size=0;
this.limit=limit;
}
//进队列
public void push(int value){
if(size==limit){
throw new RuntimeException("队列已满,不可再入队")
}
size++;
arr[pushi]=value;
pushi=nextIndex(pushi);
}
//出队列
public int pop(){
if(size==0){
throw new RuntimeException("栈为空");
}
size--;
int ans=arr[polli];
polli=nextIndex(polli);
return ans;
}
//判断是否为空
public boolean isEmpty(){
return size==0;
}
//如果现在的下标是i,返回下一个位置,
private int nextIndex(int i){
//判断i是否到了数组的最后一个位置,如果是,从0开始
return i<limit-1 ? i+1:0;
} }

(2)数组实现栈

public static class MyStack{
private int[] arr;
private int size;//记录栈的数据大小
private final int limit;//数组大小
//初始化数组
publish MyQueue(int limit){
arr=new int[limit];
size=0;
this.limit=limit;
}
//进栈
public void push(int value){
if(size==limit){
throw new RuntimeException("队列已满,不可再入队")
}else{
size++;
arr[size]=value;
}
}
//出栈
public int pop(){
if(size==0){
throw new RuntimeException("栈为空");
}
size--;
int ans=arr[size];
return ans;
}
//判断是否为空
public boolean isEmpty(){
return size==0;
}
}

3.栈和队列的常见面试题

(1)实现一个特殊的栈,在基本功能的基础上,再实现返回栈中最小元素的功能

​ 1) pop、push、getMin操作的时间复杂度都是O(1)。

​ 2)设计的栈类型可以使用现成的栈结构。

实现思路:准备两个栈,一个栈为正常的数据栈Data,一个栈Min来存放最小值,每次插入一个新数据newNum,Data正常插入,插入Min中是每次要与栈顶比较大小

public static class MyStack2{
//创建两个栈
private Stack<Integer> stackData;
private Stack<Integer> stackMin; public MyStack2(){
this.stackData=new Stack<Integer>();
this.stackMin=new Stack<Integer>();
} public void push(int newNum){
//往stackMin中放数据时,需要将数据与Min栈顶的数据进行比较,
// 以确保Min插入的每一个数据都是最新的最小值
if(this.stackMin,isEnpty()){
this.stackMin.push(newNum);
}else if(newNum<this.getmin()){
this.stackMin.push(newNum);
}else{
int newMin =this.stackMin.peek();
this.stackMin.push(newMin);
}
this.stackData.push(newNum);
}
public int pop(){
if(this.stackData.isEmpty()){
throw new RuntimeException("栈为空");
}
this.stackMin.pop();
return this.stackData.pop();
}
public int getmin(){
if (this.stackMin.isEmpty()){
throw new RuntimeException("栈为空");
}
//返回栈栈顶数据
return this.stackMin.peek();
} }

三、递归

判断递归的复杂度

Master公式

形如 T(N)= a * T(N/b)+O(N^d)(其中的a、b、d都是常数)的递归函数,可以直接通过Master公式来确定时间复杂度

如果log(b,a)< d,复杂度为O(N^d)

如果log(b,a) > d,复杂度为O(N^log(b,a))

如果log(b,a) == d,复杂度为O(N^d * logN)

四、哈希表与有序表

1.哈希表(HashMap)

1)哈希表在使用层面上可以理解为一种集合结构

2)如果只有key,没有伴随数据value,可以使用HashSet结构

3)如果既有key,又有伴随数据value,可以使用HashMap结构

4)有无伴随数据,是HashMap和HashSet唯一的区别,实际结构是一回事

5)使用哈希表增(put)、删(remove)、改(put)和查(get)的操作,可以认为时间复杂度为o(1),但是常数时间比较大

6)放入哈希表的东西,如果是基础类型,内部按值传递,内存占用是这个东西的大小

7)放入哈希表的东西,如果不是基础类型,内部按引用传递,内存占用是8字节

2.有序表(TreeMap)

1)有序表在使用层面上可以理解为一种集合结构。

2)如果只有key,没有伴随数据value,可以使用set结构

3)如果既有key,又有伴随数据value,可以使用map结构

4)有无伴随数据是set与map的唯一区别,底层的实际结构是一回事。

5)有序表和哈希表的区别是,有序表把key按顺序组织起来,而哈希表完全不组织。

6)只要是有序表,他的常见操作的时间复杂度都是O(logN)

数据结构与算法(LeetCode) 第二节 链表结构、栈、队列、递归行为、哈希表和有序表的更多相关文章

  1. Java数据结构和算法(一)线性结构之单链表

    Java数据结构和算法(一)线性结构之单链表 prev current next -------------- -------------- -------------- | value | next ...

  2. 数据结构与算法【Java】08---树结构的实际应用

    前言 数据 data 结构(structure)是一门 研究组织数据方式的学科,有了编程语言也就有了数据结构.学好数据结构才可以编写出更加漂亮,更加有效率的代码. 要学习好数据结构就要多多考虑如何将生 ...

  3. Java数据结构和算法(一)线性结构

    Java数据结构和算法(一)线性结构 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 线性表 是一种逻辑结构,相同数据类型的 ...

  4. 【学习总结】java数据结构和算法-第三章-稀疏数组和队列

    相关链接 [学习总结]尚硅谷2019java数据结构和算法 github:javaDSA 目录 稀疏数组 队列 稀疏数组 稀疏数组介绍 图示 应用实例 代码实现 SparseArray.java:与二 ...

  5. JavaScript 版数据结构与算法(三)链表

    今天,我们要讲的是数据结构与算法中的链表. 链表简介 链表是什么?链表是一种动态的数据结构,这意味着我们可以任意增删元素,它会按需扩容.为何要使用链表?下面列举一些链表的用途: 因为数组的存储有缺陷: ...

  6. Java数据结构和算法(七)——链表

    前面博客我们在讲解数组中,知道数组作为数据存储结构有一定的缺陷.在无序数组中,搜索性能差,在有序数组中,插入效率又很低,而且这两种数组的删除效率都很低,并且数组在创建后,其大小是固定了,设置的过大会造 ...

  7. 为什么我要放弃javaScript数据结构与算法(第二章)—— 数组

    第二章 数组 几乎所有的编程语言都原生支持数组类型,因为数组是最简单的内存数据结构.JavaScript里也有数组类型,虽然它的第一个版本并没有支持数组.本章将深入学习数组数据结构和它的能力. 为什么 ...

  8. 数据结构与算法之美 06 | 链表(上)-如何实现LRU缓存淘汰算法

    常见的缓存淘汰策略: 先进先出 FIFO 最少使用LFU(Least Frequently Used) 最近最少使用 LRU(Least Recently Used) 链表定义: 链表也是线性表的一种 ...

  9. 为什么我要放弃javaScript数据结构与算法(第三章)—— 栈

    有两种结构类似于数组,但在添加和删除元素时更加可控,它们就是栈和队列. 第三章 栈 栈数据结构 栈是一种遵循后进先出(LIFO)原则的有序集合.新添加的或待删除的元素都保存在栈的同一端,称为栈顶,另一 ...

  10. 剑指offer_面试题5_从尾到头打印链表(栈和递归实现)

    题目:输入一个链表的头结点,从尾到头反过来打印出每一个节点的值 考察 单链表操作.栈.递归等概念. 理解:要实现单链表的输出,那么就须要遍历.遍历的顺序是从头到尾.而节点输出的顺序是从尾到头.因此,先 ...

随机推荐

  1. CentOS 30分钟部署免费在线客服系统

    前段时间我发表了一系列文章,开始介绍基于 .net core 的在线客服系统开发过程.期间有一些朋友希望能够给出 Linux 环境的安装部署指导,本文基于 CentOS 7.9 来安装部署. 我详细列 ...

  2. 从零玩转系列之SpringBoot3-核心原理

    一.简介 1.前置知识 ● Java17 ● Spring.SpringMVC.MyBatis ● Maven.IDEA 2.环境要求 环境&工具 版本(or later) SpringBoo ...

  3. Redis核心技术与实践 01 | 基本架构:一个键值数据库包含什么?

    原文地址:https://time.geekbang.org/column/article/268262 个人博客地址:http://njpkhuan.cn/archives/redis-he-xin ...

  4. windows内核情景分析-毛德操(第一章)

    微内核操作系统的特点内核尽量缩小 windows内核包括了两大部分 操作系统内核(ntoskrnl.exe),另一部分则是迁移到了内核中即系统空间中的视窗服务(win32k.sys) 用户空间和系统空 ...

  5. Spring相关API

    ApplicationContext的继承体系 applicationContext applicationContext:接口类型,代表应用上下文,可以通过其实例获得Spring容器中的Bean A ...

  6. 【译】Visual Studio 2022 中的 Web API 开发

    在 Visual Studio 2022 中,Web 开发人员的主要场景之一是使用 ASP.NET Core 创建 Web API.在 Visual Studio 2022 17.6 的最新预览版中, ...

  7. 2021-8-5 Mysql个人练习题

    创建学校表格 CREATE TABLE `Student`( `s_id` VARCHAR(20), `s_name` VARCHAR(20) NOT NULL DEFAULT '', `s_birt ...

  8. pandas 某列不为空的行

    df = df[df['my_col'].notnull()]

  9. CTF比赛中Web的php伪协议类型题小结

    php协议类型 file:// - 访问本地文件系统 http:// - 访问 HTTP(s) 网址 ftp:// - 访问 FTP(s) URLs php:// - 访问各个输入/输出流(I/O s ...

  10. webpack是如何处理css/less资源的呢

    上一篇文章 体验了webpack的打包过程,其中js文件不需要我们手动配置就可以成功解析,可其它类型的文件,比如css.less呢? css-loader 首先,创建一个空文件夹,通过 npm ini ...