数据结构与算法之堆: 堆和实现最小堆类 (Ts, Py, Go版)

N32串口DMA接收不定长数据:空闲中断与DMA通道的协同处理 本文详细解析了在N32系列MCU中,利用串口空闲中断与DMA通道协同处理不定长数据的核心机制与实战方法。通过剖析空闲中断的触发时机、DMA的配置要点以及两者协同工作的关键时序,提供了避免数据错乱的避坑指南和完整的代码实现,旨在帮助开发者构建高效、可靠的嵌入式串口通信子系统。 阅读详情

堆

  • 堆是一种特殊的完全二叉树

    • 完全二叉树:每层节点都完全填满;最后一层,如果不是满的,则缺少右边的若干节点
  • 堆:所有节点都大于等于(最大堆)或小于等于(最小堆)它的子节点

    • 可见堆是一种有顺序的数据结构
    • 如下图所示
  • 最大堆示例

        6
      /   \
     5     3
    / \   /
    4  2 1
    
  • 最小堆示例

        1
      /   \
     3     2
    / \    /
    4  6  5
    
  • 堆的规律

    • 一个堆,如果按广度优先遍历就是 0 1 2 3 4 5,我们把0 ~ 5作为数组的下标
    • 并把节点中的值填到数组中,如此一来就可以把数组来表示一个堆了,不仅如此有公式可以获取子节点和父节点的位置关系
    • 左侧子节点的位置是 2 * index + 1
    • 右侧子节点的位置是 2 * index + 2
    • 父节点的位置是 (index - 1) / 2 的商
  • 在前端js中表示堆的示例: 这是一个最小堆的结构

          1
        /   \
      3      6
     / \    /
    5   9  8
    
  • 给这个最小堆标记下索引(下标),如下

           1(0)
        /       \
      3(1)       6(2)
     /    \      /
    5(3)  9(4)  8(5)
    
  • 上图括号中的就是在堆中的下标

  • 这个最小堆在js中的表示形式是:[1,3,6,5,9,8], 数组中对应的各个元素的下标:0,1,2,3,4,5

    • 这个规律就是按照广度优先遍历来走的
    • 也就是从上到下,从左到右
  • 堆的应用

    • 快速高效找出最大值和最小值
    • 时间复杂度O(1)
    • 找出第k个最大(小)元素
  • 解决第k个最大元素

    • 构建一个最小堆,并将元素依次插入堆中
    • 当堆的容量超过K,就删除堆顶
    • 当插入结束后,堆顶就是第k个最大元素
  • 如果要找到第k个最小元素,反过来就行,道理一致

实现一个最小堆类

  • 在类里,声明一个数组,用来装元素
  • 主要方法:插入,删除堆顶、获取堆顶、获取堆大小
  • 插入
    • 将值插入堆的底部,即数组的尾部
    • 然后上移:将这个值和它的父节点进行交换换,直到父节点小于等于这个插入的值
    • 大小为k的堆中插入元素的时间复杂度为O(logk)
      • 复杂度主要体现在上移操作中,最多循环的次数是堆的高度,因为它不断上移
      • 这个堆的高度也就是二叉树的高度,二叉树的高度和树节点数量的关系是logk
      • 所以时间复杂度是O(logk)
  • 删除堆顶
    • 用数组尾部元素替换堆顶(直接删除堆顶会破坏堆结构)
    • 然后下移,将新堆顶和它的子节点进行交换,直到子节点大于等于这个新堆顶
    • 大小为k的堆中删除堆顶的事件复杂度为O(logk)
      • 和插入一样的道理,下移次数最大是堆的高度,所以时间复杂度也是logk
  • 获取堆顶:返回数组的头部
  • 获取堆的大小:返回数组的长度

Typescript 版算法实现


1 ) 方案1

class MinHeap {
    heap: number[] = [];

    // 获取父节点
    getParentIndex(i: number): number {
        return (i - 1) >> 1;
    }

    // 获取左子节点
    getLeftIndex(i: number): number {
        return (i << 1) + 1;
    }

    // 获取右子节点
    getRightIndex(i: number): number {
        return (i << 1) + 2;
    }

    // 两数交换
    swap(i: number, j: number): void {
        // 写法1, 比较繁琐
        // let temp = this.heap[i];
        // this.heap[i] = this.heap[j];
        // this.heap[j] = temp;

        // 写法3 对象结构,别名的方式
        // let a = 1,b = 2;
        // {a:b,b:a} = {a,b}


        // 写法2 通过数学运算加减关系,利用两个数字在坐标轴上的距离固定来交换
        // let a = 1,b = 2;
        // b = b - a; // b(原) - a(原)
        // a = a + b;  // a(原) + b(原) - a(原)
        // b = a - b;  // b(原) - (b(原) - a(原))
        // console.log(a); //2
        // console.log(b); //1

        // 使用es6解构数组赋值来交换两数
        [this.heap[j], this.heap[i]] = [this.heap[i], this.heap[j]];
    }

    // 上移操作封装 是个递归
    shiftUp(i: number): void {
        if (!i) return;
        const pi = this.getParentIndex(i);
        if (this.heap[pi] > this.heap[i]) {
            this.swap(pi, i);
            this.shiftUp(pi);
        }
    }

    // 下移操作
    shiftDown(i: number): void {
        const size = this.size();
        const li = this.getLeftIndex(i);
        const ri = this.getRightIndex(i);
        const cur = this.heap[i];

        let smallest = i;
        if (li < size && this.heap[li] < cur) {
            smallest = li;
        }
        if (ri < size && this.heap[ri] < this.heap[smallest]) {
            smallest = ri;
        }

        if (smallest !== i) {
            this.swap(smallest, i);
            this.shiftDown(smallest);
        }
    }

    // 添加
    insert(value: number): void {
        this.heap.push(value);
        this.shiftUp(this.heap.length - 1);
    }

    // 删除
    pop(): void {
        if (this.size() === 0) return;
        this.heap[0] = this.heap.pop()!;
        this.shiftDown(0);
    }

    // 获取堆顶
    peak(): number | undefined {
        return this.heap[0];
    }

    // 获取堆大小
    size(): number {
        return this.heap.length;
    }

    // 输出最后的堆结构, 有参,输出参数;无参,输出堆结构
    print(o?: any): void {
        console.log(o ? o : this.heap);
    }
}

// 测试用例
const heap = new MinHeap();

// 测试插入操作
heap.insert(3);
heap.insert(1);
heap.insert(6);
heap.insert(5);
heap.insert(2);
heap.insert(4);

console.log("After insertions:");
heap.print(); // 应该输出 [1, 3, 2, 5, 6, 4]

// 测试获取堆顶元素
console.log("Peek:", heap.peak()); // 应该输出 1

// 测试删除堆顶元素
heap.pop();
console.log("After pop:");
heap.print(); // 应该输出 [2, 3, 4, 5, 6]

// 测试再次删除堆顶元素
heap.pop();
console.log("After another pop:");
heap.print(); // 应该输出 [3, 5, 4, 6]

// 测试获取堆的大小
console.log("Size:", heap.size()); // 应该输出 4

// 测试空堆的情况
const emptyHeap = new MinHeap();
console.log("Empty heap peek:", emptyHeap.peak()); // 应该输出 undefined
emptyHeap.pop();
console.log("Empty heap size after pop:", emptyHeap.size()); // 应该输出 0

Python3 版算法实现


1 ) 方案1


class MinHeap:
    def __init__(self):
        self.heap = []

    # 获取父节点
    def get_parent_index(self, i):
        return (i - 1) >> 1

    # 获取左子节点
    def get_left_index(self, i):
        return (i << 1) + 1

    # 获取右子节点
    def get_right_index(self, i):
        return (i << 1) + 2

    # 两数交换
    def swap(self, i, j):
        self.heap[i], self.heap[j] = self.heap[j], self.heap[i]

    # 上移操作封装 是个递归
    def shift_up(self, i):
        if i == 0:
            return
        pi = self.get_parent_index(i)
        if self.heap[pi] > self.heap[i]:
            self.swap(pi, i)
            self.shift_up(pi)

    # 下移操作
    def shift_down(self, i):
        size = self.size()
        li = self.get_left_index(i)
        ri = self.get_right_index(i)
        cur = self.heap[i]

        smallest = i
        if li < size and self.heap[li] < cur:
            smallest = li
        if ri < size and self.heap[ri] < self.heap[smallest]:
            smallest = ri

        if smallest != i:
            self.swap(smallest, i)
            self.shift_down(smallest)

    # 添加
    def insert(self, value):
        self.heap.append(value)
        self.shift_up(len(self.heap) - 1)

    # 删除
    def pop(self):
        if self.size() == 0:
            return
        self.heap[0] = self.heap.pop()
        self.shift_down(0)

    # 获取堆顶
    def peak(self):
        if self.size() == 0:
            return None
        return self.heap[0]

    # 获取堆大小
    def size(self):
        return len(self.heap)

    # 输出最后的堆结构
    def print(self):
        print(self.heap)

def main():
    # 测试用例
    heap = MinHeap()

    # 测试插入操作
    heap.insert(3)
    heap.insert(1)
    heap.insert(6)
    heap.insert(5)
    heap.insert(2)
    heap.insert(4)

    print("After insertions:")
    heap.print()  # 应该输出 [1, 2, 4, 5, 3, 6]

    # 测试获取堆顶元素
    peek = heap.peak()
    print("Peek:", peek)  # 应该输出 1

    # 测试删除堆顶元素
    heap.pop()
    print("After pop:")
    heap.print()  # 应该输出 [2, 3, 4, 5, 6]

    # 测试再次删除堆顶元素
    heap.pop()
    print("After another pop:")
    heap.print()  # 应该输出 [3, 5, 4, 6]

    # 测试获取堆的大小
    print("Size:", heap.size())  # 应该输出 4

    # 测试空堆的情况
    empty_heap = MinHeap()
    peek_empty = empty_heap.peak()
    print("Empty heap peek:", peek_empty)  # 应该输出 None
    empty_heap.pop()
    print("Empty heap size after pop:", empty_heap.size())  # 应该输出 0

if __name__ == "__main__":
    main()

Golang 版算法实现


1 ) 方案1

/*
堆和实现最小堆类
*/

package main

import (
	"fmt"
)

type MinHeap struct {
	heap []int
}

// 获取父节点
func (h *MinHeap) getParentIndex(i int) int {
	return (i - 1) >> 1
}

// 获取左子节点
func (h *MinHeap) getLeftIndex(i int) int {
	return (i << 1) + 1
}

// 获取右子节点
func (h *MinHeap) getRightIndex(i int) int {
	return (i << 1) + 2
}

// 两数交换
func (h *MinHeap) swap(i, j int) {
	h.heap[i], h.heap[j] = h.heap[j], h.heap[i]
}

// 上移操作封装 是个递归
func (h *MinHeap) shiftUp(i int) {
	if i == 0 {
		return
	}
	pi := h.getParentIndex(i)
	if h.heap[pi] > h.heap[i] {
		h.swap(pi, i)
		h.shiftUp(pi)
	}
}

// 下移操作
func (h *MinHeap) shiftDown(i int) {
	size := h.size()
	li := h.getLeftIndex(i)
	ri := h.getRightIndex(i)
	cur := h.heap[i]

	smallest := i
	if li < size && h.heap[li] < cur {
		smallest = li
	}
	if ri < size && h.heap[ri] < h.heap[smallest] {
		smallest = ri
	}

	if smallest != i {
		h.swap(smallest, i)
		h.shiftDown(smallest)
	}
}

// 添加
func (h *MinHeap) insert(value int) {
	h.heap = append(h.heap, value)
	h.shiftUp(len(h.heap) - 1)
}

// 删除
func (h *MinHeap) pop() {
	if h.size() == 0 {
		return
	}
	h.heap[0] = h.heap[len(h.heap)-1]
	h.heap = h.heap[:len(h.heap)-1]
	h.shiftDown(0)
}

// 获取堆顶
func (h *MinHeap) peak() *int {
	if h.size() == 0 {
		return nil
	}
	return &h.heap[0]
}

// 获取堆大小
func (h *MinHeap) size() int {
	return len(h.heap)
}

// 输出最后的堆结构
func (h *MinHeap) print() {
	fmt.Println(h.heap)
}

func main() {
	// 测试用例
	heap := &MinHeap{}

	// 测试插入操作
	heap.insert(3)
	heap.insert(1)
	heap.insert(6)
	heap.insert(5)
	heap.insert(2)
	heap.insert(4)

	fmt.Println("After insertions:")
	heap.print() // 应该输出 [1, 2, 4, 5, 3, 6]

	// 测试获取堆顶元素
	peek := heap.peak()
	if peek != nil {
		fmt.Println("Peek:", *peek) // 应该输出 1
	} else {
		fmt.Println("Peek: nil")
	}

	// 测试删除堆顶元素
	heap.pop()
	fmt.Println("After pop:")
	heap.print() // 应该输出 [2, 3, 4, 5, 6]

	// 测试再次删除堆顶元素
	heap.pop()
	fmt.Println("After another pop:")
	heap.print() // 应该输出 [3, 5, 4, 6]

	// 测试获取堆的大小
	fmt.Println("Size:", heap.size()) // 应该输出 4

	// 测试空堆的情况
	emptyHeap := &MinHeap{}
	peekEmpty := emptyHeap.peak()
	if peekEmpty != nil {
		fmt.Println("Empty heap peek:", *peekEmpty) // 应该输出 nil
	} else {
		fmt.Println("Empty heap peek: nil")
	}
	emptyHeap.pop()
	fmt.Println("Empty heap size after pop:", emptyHeap.size()) // 应该输出 0
}
南京理工大学计算机预推免面试(双非重点关注) 南京理工大学总体来说对双非学校比较友好,上岸率比较高,而且面试形式是线上,在预推免的过程中,可以作为重点关注的学校,但是一定要注意南理报名截止的时间,部分学校可能保研名额公示的比较晚,对于保研边缘人来说很可能会错过,我的建议是,即使不确定能否拿到保研名额,先查一下截止时间,先在系统上报名!!一旦拿到了offer,就是铁的,保底专硕,而且有很大的技巧性,一定要认真看哈!!!每个人的情况可能都不一样,如果有需要帮忙可以私我~~~ 阅读详情

相关推荐

从零开始:在Unity中使用Dynamic Bone实现角色骨骼自然抖动(以女性角色胸部为例)

本文详细介绍了在Unity中使用Dynamic Bone插件实现角色骨骼自然抖动的完整流程,特别以女性角色胸部为例。从插件导入、骨骼系统基础到Dynamic Bone组件配置和参数调优,提供了全面的技术指导。文章还包含性能优化技巧和常见问题解决方案,帮助开发者快速掌握这一物理效果实现方法。

weixin_28728495的博客 457

实验10.1 堆的操作

实验10.1 堆的操作

知识库搭建ing 885

《数据结构》04-树4 是否同一棵二叉搜索树

题目 给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。 输入格式: 输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要...

叫我皮卡丘 2013

Vj数据结构实验10(一)

内容 创建最小堆类。最小堆的存储结构使用数组。提供操作:插入、删除、初始化。题目第一个操作是建堆操作,接下来是对堆的插入和删除操作,插入和删除都在建好的堆上操作。 格式 输入 第一行一个数n(n<=5000),代表堆的大小。第二行n个数,代表堆的各个元素。 第三行一个数m (m<=1000),代表接下来共m个操作。接下来m行,分别代表各个操作。下面是各个操作的格式: 插入操作:1 num 删除操作:2 排序操作:第一行两个数3和n,3代表是排序操作,n代表待排序的数的数目,接下..

weixin_53437436的博客 647

YOLOv8改进002:添加小目标检测头(小目标检测大量涨点)

YOLOv8 目标检测算法改进之添加小目标检测头,亲测在小目标检测的数据集上有大幅度的涨点效果(mAP直接涨了 0.04 左右)。

m0_46496775的博客 9878

UE5高斯泼溅落地全链路:从PLY导入到实时渲染的工程实践

3D高斯泼溅(3D Gaussian Splatting)正从NeRF后处理技术演进为新一代隐式几何渲染范式,其核心在于以可微椭球体替代传统三角面片,通过协方差矩阵与球谐系数实现高质量体素化渲染。该技术突破点云精度瓶颈,但与UE5现有资产管线存在根本性不兼容——静态网格导入器无法解析scale/rot/sh系数等非标顶点语义,标准光栅化管线亦无法执行高斯核采样计算。XV3DGS-UEPlugin通过自定义资产类型、StructuredBuffer GPU数据流与专用材质节点,将高斯泼溅重构为可编辑、可LOD

weixin_33692177的博客 360

C++实现最小堆创建,删除与插入

数据结构 最小堆操作

qinziyi061015的博客 344

【Windows Server 2019】邮件服务器配置与管理——安装及配置Winmail服务器(上)

博文介绍了如何安装邮件服务器 Winmail,如何配置Winmail,包括运行服务器,Winmail管理工具介绍和域名配置。

VMware, Windows, Linux, Cisco, Container, Kubernetes, Kali 2万+

数据结构——小顶堆的构建,添加,删除

...

wenge1477的博客 1万+

A-Frame引擎开发:A-Frame基础入门_(11).A-Frame物理引擎集成

在上一节中,我们学习了如何在A-Frame中创建基本的3D场景和交互元素。然而,为了使虚拟现实游戏更具真实感和互动性,物理引擎的集成是必不可少的。物理引擎可以模拟现实世界中的物理行为,如重力、碰撞、摩擦等,从而增强用户的沉浸感。物理引擎在虚拟现实游戏中的重要性不言而喻。它不仅能够模拟物体的运动和相互作用,还能为游戏提供更真实的反馈和体验。例如,当玩家在虚拟世界中推动一个物体时,物理引擎可以确保物体按照预期的方式移动,而不是简单地穿墙而过或突然消失。重力是物理引擎中最基本的特性之一。在A-Frame中,我们可

chenlz2007的博客 798

基于Python的房地产评估数据抓取与分析 —— 房价走势与市场报告

在房地产行业中,了解和分析房产价格的变化趋势、各个地区的房价差异以及市场评价报告,可以帮助投资者、购房者以及政策制定者做出更加明智的决策。本文介绍了如何使用Python爬虫技术抓取房地产平台上的房产评估报告、价格走势等数据,并对抓取的数据进行分析。通过这些技术,您可以自动化抓取房地产平台的数据,分析房价走势,获取市场报告,为房地产投资决策提供数据支持。假设我们要从链家网抓取某个房产的价格、房产描述以及历史成交价格,首先需要获取目标房产页面的URL,并发送HTTP请求。伪装为常见浏览器,避免被识别为爬虫。

2201_76125261的博客 848

JavaScript实现堆结构

堆的数据结构是完全二叉树或一堆数组,因为堆在逻辑上是一棵完全二叉树,在物理结构上是一个一维数组。堆将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等。堆是非线性数据结构,相当于一维数组,有两个直接后继。堆就是用数组实现的二叉树,所以它没有使用父指针或者子指针。堆根据“堆属性”来排序,“堆属性”决定了树中节点的位置。

Twinkle_sone的博客 1007

cesium 淹没分析

cesium淹没分析

God's asylum的博客 482

数据结构与算法之堆: 实现最大堆类的两种方式及实现堆排序 (Ts, Py, Go版)

1 )方案一:参考最小堆类实现最大堆类及实现排序。2 )方案二:另一种方式实现最大堆类及实现排序。

Wang的专栏 334

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

数据结构与算法之贪心: LeetCode 455. 分饼干 (Ts, Py, Go版)

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j]。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。2 )排序 + 双指针 + 贪心。1 )排序 + 遍历。

Wang的专栏 1568

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

数据结构与算法之堆: LeetCode 215. 数组中的第K个最大元素 (Ts, Py, Go版)

1 )基于js中原生sort api。2 )基于堆的数据结构和堆排序的方法。3 )基于冒泡排序。 4 ) 基于快速排序。

Wang的专栏 481

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

数据结构与算法之排序: 选择排序 (Ts, Py, Go版)

数据结构与算法之排序: 选择排序

Wang的专栏 442

数据结构与算法之二叉树: LeetCode 111. 二叉树的最小深度 (Ts, Py, Go版)

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。就 给定一个二叉树,找出其最小深度。说明:叶子节点是指没有子节点的节点。

Wang的专栏 699

数据结构与算法之堆: LeetCode 347. 前K个高频元素 (Ts, Py, Go版)

【代码】数据结构与算法之堆: Leetcode 347. 前K个高频元素 (Typescript版)

Wang的专栏 477

Hello 算法堆章节练习精讲:从「10 入堆」到「第 k 大元素」的完整拆解

本文以《Hello 算法》(仓库 `hello-algo`)[堆章节课后练习](https://link.gitcode.com/i/f199f13f10316564d0caad7dd12dbd2f) 为骨架,逐题拆解三类核心考察点:**大顶堆元素入堆时的向上堆化**、**基于数组索引的小顶堆父子关系校验**,以及**用小顶堆在线维护最大 k 个数(Top-k)**。文章不仅给出完整推导过程与答案

gitblog_00013的博客 871

Hello 算法堆章节核心速查:优先队列、堆化、建堆与 Top-k 问题的原理与代码验证

> 本文为 [Hello 算法](https://link.gitcode.com/i/4bce3e70dd58a8470ea02ac232b483cb) 英文版堆章节([en/docs/chapter_heap](https://link.gitcode.com/i/103f403cff87f6df8e626ba6c173ce7b))的系统性复习指南,以章节总结 [summary.md](htt

gitblog_01087的博客 529

数据结构与算法之字符串: LeetCode 696. 计数二进制子串 (Ts, Py, Go, Java版)

给定一个字符串 s,统计并返回具有相同数量 0 和 1 的非空(连续)子字符串的数量,并且这些子字符串中的所有 0 和所有 1 都是成组连续的。重复出现(不同位置)的子串也要统计它们出现的次数。

Wang的专栏 1103

数据结构与算法之排序: 桶排序 (Ts, Py, Go版)

桶排序的时间复杂度 在 O(n) ~ O(n2n^2n2普通桶排序并不普遍应用是拆分为桶后,在每个桶内还需要排序,意义就不大了而且要考虑每个桶内用什么样的数据结构来存储(考虑到内部排序)如果还用数组就极大浪费了空间(需使用最大的空间, 不同语言有区别)一般可以使用链表,但是对链表排序又开始麻烦了桶排序优化空间,时间上就会增加;优化时间空间上又会增多, 取一个时间和空间的平衡。

Wang的专栏 416

数据结构与算法之排序: 计数排序 (Ts, Py, Go版)

计数排序的适用范围有限:最优版时间复杂度可降低到 O(n), 是最快的排序算法, 但是有两个前提需要满足1)需要排序的元素必须是非负整数(下标不能是负数和小数 2)排序元素的取值要在一定范围内,并且比较集中满足以上两个条件,才能最大发挥出计数排序的优势, 否则不适用计数排序的缺点基础版空间浪费,优化版解决了这个问题将数组长度定为 max-min+1, 即不仅要找出最大值,还要找出最小值缺点弥补:根据两者的差来确定计数数组的长度则可弥补之计数排序是非常稳定的排序算法,但是适用场景确实有限。

Wang的专栏 429

Hello 算法:Top-k 问题深度剖析——如何用最小堆从无序数组中高效找出最大的 k 个元素

Top-k 问题(Top-k Problem)是堆(heap)章节中一个极具工程价值的经典算法问题:给定一个长度为 $n$ 的无序数组 `nums`,要求返回其中最大的 $k$ 个元素。本文基于 [Hello 算法](https://link.gitcode.com/i/32d346e5ee23cb802c4efbdc7719e899) 开源仓库中英文版 [Top-k 问题章节](https://

gitblog_00709的博客 426

数据结构与算法之字典: LeetCode 76. 最小覆盖子串 (Ts, Py, Go版)

1 )双指针滑动窗口遍历

Wang的专栏 349
上一篇: 数据结构与算法之字典: LeetCode 76. 最小覆盖子串 (Ts, Py, Go版)
下一篇: 数据结构与算法之堆: LeetCode 215. 数组中的第K个最大元素 (Ts, Py, Go版)
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值