4.数据结构之通用链表实现

操作系统:Pintos Project 1 也是借鉴了网上一些实现,勉勉强强将Project1过了,不过感觉代码中还是有些问题的。alarm测试集这个测试集要求重新实现timer_sleep()函数,将原来的忙等待改为非忙等待。 思路跟阻塞线程类似: 1.为线程增加一个新的状态,表示线程正处在sleep中。 thread.h:在文件靠前添加宏定义: #define THREAD_SLEEP THREAD_BLOCKED 2.在内核中增加一 阅读详情

数据结构之通用链表实现

通用链表简介

在redis数据库和acl库中,通用双端链表的应用随处可见。之前我们接触过链表的相关操作,前两章:《数据结构之单链表》以及《数据结构之链表面试题》接触了不少链表的问题,但是对于问题的处理总是无法逃脱类型的限定,所以我们需要将类型的问题从数据结构中剥离出来。具体的类型在数据结构的使用者进行具体的限定。好吧,我们首先来看看头文件dlist.h中关于链表节点结构的定义和接口的声明:

//防止头文件的内容被重复包含
#ifndef _DLIST_H_
#define _DLIST_H_

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

#define ZERO       (0)
#define ONLY_ONE   (1)
#define TRUE       (1)
#define FALSE      (0)

struct Dlist;
typedef struct Dlist Dlist;             //双端链表控制信息

struct Dlist_node;
typedef struct Dlist_node Dlist_node;   //双短链表节点信息

typedef unsigned char Boolean;          //C语言中的布尔值

//链表控制信息
struct Dlist{   
    struct Dlist_node *head;   //指向双端链表的头节点
    struct Dlist_node *tail;   //指向双端链表的尾节点
    int               count;   //双端链表中的元素个数

    //释放链表节点数据域
    void    (*free)(void *ptr);    //void (*)(void *ptr)  free;
    //匹配链表节点数据域
    Boolean (*match)(void *val1, void *val2);
    //拷贝链表节点数据域
    void    *(*copy_node)(void *src);
};

//链表节点信息
struct Dlist_node{
    struct Dlist_node *prev;    //前一个节点指针
    struct Dlist_node *next;    //后一个节点指针
    void              *data;    //数据(指针)
};

typedef void (*Print_func)(void *value);

//双端链表的接口(ADT)
Dlist      *init_dlist(void)                    ;    //链表的初始化
void       destroy_dlist(Dlist **dlist)         ;    //链表的销毁
Boolean    push_front(Dlist *dlist, void *value);    //链表头部插入
Boolean    push_back(Dlist *dlist, void *value) ;    //链表尾部插入
Boolean    pop_back(Dlist *dlist)               ;    //链表尾部删除
Boolean    pop_front(Dlist *dlist)              ;    //链表头部删除
Boolean    insert_prev_node(Dlist *dlist,
             Dlist_node *node, void *value)     ;    //插入指定节点的前边
Boolean    insert_next_node(Dlist *dlist,
             Dlist_node *node, void *value)     ;    //插入指定节点的后边
Boolean    remove_dlist_node(Dlist *dlist,
             Dlist_node *node, void **value)             ;    //删除链表中的节点    
void       print_dlist(Dlist *dlist, Print_func print)   ;    //打印双端链表
Dlist_node  *get_index_node(Dlist *dlist, int index)     ;    //得到下标为index的链表元素
Boolean    get_front(Dlist *dlist, void **value)         ;    //得到链表头节点的数据域
Boolean    get_tail(Dlist *dlist, void **value)          ;    //得到链表尾节点的数据域
int        get_dlist_count(Dlist *dlist)                 ;    //得到链表元素个数


//
void print_int(void *value);    //打印整形值

#endif

在参数传递中我们对于数据的传递都是采用的指针的传递,并且都是void *类型,这样就可以接受任意类型的数据。在结构上我们依然设计了链表控制信息和链表节点信息两部分,这里我们使用了函数指针的技术,函数指针可以让该指针指向相同类型的函数(返回值和参数列表相同)。首先我们得定义出函数指针的这种类型:

typedef void (*Print_func)(void *value);

这就是说Print_func是一种类型,这种类型可以定义相关指针,该指针可以指向型如
void func1(void *value)类型的函数。

关于链表接口的实现我们在dlist.c中进行实现,代码如下所示:

#include "dlist.h"
#include "tools.h"


void       destroy_dlist(Dlist **dlist)    //链表的销毁
{
    Dlist_node *p_node = NULL;

    if(dlist == NULL || *dlist == NULL){
        return ;
    }

    p_node = (*dlist)->head;

    while((*dlist)->head != NULL){
        (*dlist)->head = p_node->next;
        if((*dlist)->free != NULL){
            (*dlist)->free(p_node->data);
        }
        free(p_node);
        p_node = (*dlist)->head;
    }
    free(*dlist);
    *dlist = NULL;

}

static Dlist_node *buy_node(void)
{
    Dlist_node *result = (Dlist_node *)Malloc(sizeof(Dlist_node));
    bzero(result, sizeof(Dlist_node));

    return result;
}

Boolean    push_front(Dlist *dlist, void *value)    //链表头部插入
{
    Dlist_node *node = NULL;

    if(dlist == NULL || value == NULL){
        return FALSE;
    }

    node = buy_node();
    node->data = value;

    if(dlist->count == ZERO){    //链表没有元素时
        dlist->head = dlist->tail = node;
    }else{
        node->next = dlist->head;
        dlist->head->prev = node;
        dlist->head = node;
    }
    dlist->count++;
    return TRUE;
}

Boolean    push_back(Dlist *dlist, void *value)    //链表尾部插入
{
    Dlist_node *node = NULL;

    if(dlist == NULL || value == NULL){
        return FALSE;
    }

    node = buy_node();
    node->data =value;

    if(dlist->count == ZERO){
        dlist->head = dlist->tail = node;
    }else{
        node->prev = dlist->tail;
        dlist->tail->next = node;
        dlist->tail = node;
    }
    dlist->count++;
    return TRUE;
}
Boolean    pop_back(Dlist *dlist)    //链表尾部删除
{
    Dlist_node *p_node = NULL;

    if(dlist == NULL || dlist->count == ZERO){
        return FALSE;
    }

    p_node = dlist->tail;

    if(dlist->count == ONLY_ONE){
        dlist->head = dlist->tail = NULL;
    }else{
        dlist->tail = p_node->prev;
        dlist->tail->next = NULL;
    } 
    if(dlist->free != NULL){
        dlist->free(p_node->data);
    }
    free(p_node);
    dlist->count--;
    return TRUE;
}
Boolean    pop_front(Dlist *dlist)    //链表头部删除
{
    Dlist_node *p_node = NULL;

    if(dlist == NULL || dlist->count == ZERO){
        return FALSE;
    }

    p_node = dlist->head;

    if(dlist->count == ONLY_ONE){
        dlist->head = dlist->tail = NULL;
    }else{
        dlist->head = p_node->next;
        dlist->head->prev = NULL;
    }
    if(dlist->free != NULL){
        dlist->free(p_node->data);
    }
    free(p_node);
    dlist->count--;
    return TRUE;
}

Dlist_node *get_index_node(Dlist *dlist, int index)   //得到下标为index的链表节点
{
    Dlist_node *node = NULL;
    int move_count = 0;

    if(dlist == NULL || dlist->count == ZERO
    || index < ZERO || index >= dlist->count){
         return NULL;
    }

    node = dlist->head;
    move_count = index;

    //找到指定下标元素
    while(move_count--){
        node = node->next;
    }

    return node;
}

Boolean    remove_dlist_node(Dlist *dlist, 
               Dlist_node *node, void **value)    //删除指定节点
{
    if(dlist == NULL || node == NULL){
        return FALSE;
    }

    if(value != NULL){    //取得被删除节点数据域信息
        *value = node->data;
    }

    if(node->next == NULL){    //node在尾部
        pop_back(dlist);
    }else if(node->prev == NULL){
        pop_front(dlist);
    }else{
        node->prev->next = node->next;
        node->next->prev = node->prev;
        if(dlist->free != NULL){
            dlist->free(node->data); 
        }
        free(node);   //Free(node)
        dlist->count--;

        /*
 *
 * #define Free(node) (node->prev->next = node->next;) \
 *                    (node->next->prev = node->prev;) \
 *                    
 *
 * */
    }
    return TRUE;
}

Boolean    insert_next_node(Dlist *dlist,
               Dlist_node *node, void *value)    //插入到指定节点的后边
{
    Dlist_node *p_node = NULL;

    if(dlist == NULL || node == NULL || value){
        return FALSE;
    }

    p_node = buy_node();
    p_node->data = value;

    p_node->prev = node;
    p_node->next = node->next;
    if(node->next == NULL){
        dlist->tail = p_node;
    }else{
        node->next->prev = p_node;
    }
    node->next = p_node;
    dlist->count++;
    return TRUE;
}

Boolean    insert_prev_node(Dlist *dlist,
               Dlist_node *node, void *value)    //插入到指定节点的前边
{
    Dlist_node *p_node = NULL;

    if(dlist == NULL || node == NULL || value == NULL){
        return FALSE;
    }

    p_node = buy_node();
    p_node->data = value;

    //进行插入操作
    p_node->next = node;
    p_node->prev = node->prev;
    if(node->prev == NULL){    //node为第一个节点
        dlist->head = p_node;
    }else{    //node不是第一个节点
        node->prev->next = p_node;
    }
    node->prev = p_node;
    dlist->count++; 
    return TRUE;
}

void print_int(void *value)
{
    printf("%d ", *(int *)value);
}

void print_dlist(Dlist *dlist, Print_func print)    //打印链表信息
{
    Dlist_node *p_node = NULL;

    if(dlist == NULL || dlist->count == ZERO){
        return ;
    }

    for(p_node = dlist->head; p_node ; p_node = p_node->next){
        print(p_node->data);
    }
    printf("\n");
}


Dlist *init_dlist(void)    //双端链表的初始化
{
    Dlist *dlist = NULL; 

    dlist = (Dlist *)Malloc(sizeof(Dlist));
    bzero(dlist, sizeof(Dlist));   //对dlist进行初始化

    return dlist;
}

Boolean get_front(Dlist *dlist, void **value)
{
    if(dlist == NULL || dlist->count == ZERO){
        return FALSE;
    }

    if(value != NULL){
        *value = dlist->head->data;
    }
    return TRUE;
}

Boolean get_tail(Dlist *dlist, void **value)
{
    if(dlist == NULL || dlist->count == ZERO){ 
        return FALSE;
    }

    if(value != NULL){
         *value = dlist->tail->data;
    }
    return TRUE;
}

int get_dlist_count(Dlist *dlist)
{
    if(dlist == NULL){
        return -1;
    }
    return dlist->count;
}

在dlist.c文件中我们包含了一个tools.h,这个是我们的工具类文件,其中包含了对内存和简单算法的相关接口,分为tools.h和tools.c两个文件:

#ifndef _TOOLS_H_
#define _TOOLS_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void *Malloc(size_t size);   //申请堆空间
void swap(void *a, void *b, int length);   //交换任意两个值
#endif

对应的tools.c文件:

#include "tools.h"

void *Malloc(size_t size)
{
    void *result = malloc(size);
    if(result == NULL){ 
        fprintf(stderr, "the memory is full!\n");
        exit(1);
    } 
    return result;
}

void swap(void *a, void *b, int length)
{
    void *temp = malloc(length);
    memcpy(temp, a, length);
    memcpy(a, b, length);
    memcpy(b, temp, length);

    free(temp);
}

关于通用链表的测试代码入下所示:

//通用链表测试代码
#include <stdio.h>
#include "dlist.h"

int main(int argc, char **argv)
{
    Dlist *dlist1 = NULL;
    int array[] = {12, 23, 34, 4, 1, 33, 24};
    int array1[] = {1, 33, 44, 2, 33, 222, 444};
    int arr_len = sizeof(array) / sizeof(array[0]);
    int i  = 0;   

    dlist1 = init_dlist();   //双端链表的初始化
    //初始化完成后,如果有需要,应修改free、match和dup的指向

    for(i = 0; i < arr_len; ++i){
        push_back(dlist1, &array[i]);       
    }

    print_dlist(dlist1, print_int);
    pop_back(dlist1);

    push_front(dlist1, &array1[2]);


    print_dlist(dlist1, print_int);

    destroy_dlist(&dlist1);    //双端链表的销毁
    return 0;
}

通用链表在redis数据库中具有着非常多的应用:
可以作为底层容器的实现,用来改造,添加保存节点长度的字段。或者说python的基本数据类型列表、元组的底层容器。以及后期我们将要使用适配器模式对通用双端链表进行封装,创建出栈和队列。

敬请期待!

数据结构 | 通用数据类型双向链表(C语言) 目录前言设计思路代码展示测试环节 前言 熟悉C++的STL(标准模板库)的人都知道list底层是一个双向链表,支持通用类型数据的存储,使用起来非常方便,但对于C语言开发者来说,并没有这么方便的工具,所以在这里记录一下自己实现的通用数据类型双向链表,提供了一些常见的API,并分享一些常见的代码规范。 设计思路 这里我们不便过多地讨论双向链表的实现过程,我们重点看如何解决下面几个问题 1. 如何解决通用类型的数据存储 2. 如何保证代码的严谨性,健壮性 3. 如何实现数据结构的高复用,低耦合 1.通过 阅读详情

相关推荐

Pintos基础数据结构:通用链表

由于具体应用中仍然需要对存储于‘链表结点’中的数据进行访问,因此,就需要从指向‘链表元素’的指针推算出包含它的那个‘链表结点’的指针。为此,PINTOS 中引入了一个宏 list_entry,其定义和基本思想如图所示:如果已知某个‘链表元素’的指针为 p,并且该‘链表元素’以字段 elem 的形式包含在‘链表结点’结构 list_nodei 中,宏调用list_entry(p,structlist_nodei,elem)经过展开后就是指向包含该‘链表元素’的‘链表结点’的指针。那么这个指针变量怎么定义呢?

Junds0的博客 1686

基础数据结构:链表

模拟实现基础数据结构-单链表

m0_62126248的博客 674

从零配置到稳定运行:A4988步进电机驱动模块的实战避坑指南

本文详细介绍了A4988步进电机驱动模块的配置与优化技巧,涵盖硬件连接、电流调节、微步设置及散热优化等关键环节。通过实战经验分享,帮助用户避开常见陷阱,实现步进电机的稳定运行,特别适合单片机开发者和3D打印机爱好者参考。

weixin_28452161的博客 165

PintOS Lab1

PintOS操作系统Lab1

tgkyrie的博客 1230

利用ANSYS随机振动分析功能实现随机疲劳分析

本文介绍了ANSYS随机振动分析功能,以及利用该功能,按照Steinberg提出的基于高斯分布和Miner线性累计损伤定律的三区间法进行ANSYS随机疲劳计算的具体过程。在工程应用中,汽车、飞行器、船舶以及其它各种机械或零部件,大多是在随机载荷作用下工作,当它们承受的应力水平较高,工作达到一定时间后,经常会突然发生随机疲劳破坏,往往造成灾难性的后果。因此,预测结构或零部件的随机疲劳寿命是非常有必要的。在工程界,疲劳计算广泛采用名义应力法,即以S-N曲线为依据进行寿命估算的方法,可以直接得到总寿命。

qq_38220914的博客 7608

【Labview与SQL Server互联(labview可以引用数据库)】

Labview与SQL Server互联

Magize的博客 3585

通用链表---通用链表的基本使用

通用链表 学习使用通用链表之前肯定写过的单向链表或者双向链表,以上两种链表在同一条链上只能挂在同一类型的结构体,因为不同结构体中的指针域类型不相同,所以通用链表很好的解决了这个问题,说到这里,相信在你的脑海已经有了通用链表的架构了,接下来我来详细的介绍一下通用链表的创建和基本应用。 1.双向链表和通用链表图解对比 1.1 双向链表指针域图解 从图中可以看出双向链...

cc_light_boy的博客 3450

双向晶闸管交流调压基础知识及Multisim电路仿真

本文介绍了双向晶闸管交流调压电路的工作原理及应用。该电路由双向晶闸管、RC移相电路和双向触发二极管组成,通过调节电位器改变触发角实现电压调节。当电位器阻值减小时,触发角减小,输出电压升高;阻值增大时,触发角增大,输出电压降低。Multisim仿真展示了不同电位器档位下的波形特征:0%档位时全导通,50%档位时半导通,100%档位时基本关断。该电路结构简单、调节平滑,广泛应用于调光、调速等场合,但会产生谐波干扰。

XU157303764的博客 837

【数据结构与算法】详解什么是链表,并用代码手动实现一个链表结构

本文将来讲解一下一种常见的线性数据结构—链表,因为链表和数组一样都是一种线性的数据结构,但是它俩的实现原理是完全不同的,所以在讲解链表之前,我们来回顾一下 数组 结构。

零一的博客 1万+

Endnote 导入参考文献的时候,格式错误太多了。et.al错误,国标GBT7714在endnote中的详细配置教程,适用于本科,硕士论文文献插入的模板

EndNote插入文献常遇到以下错误主要如下: 等、et al不分; 英文作者全名大写; 期刊名字使用了缩写(图片里没有体现;卷号、期号缺失时出现乱码,多了半个括号;页码范围略去了相同部分;没有悬挂缩进,本文全部解决,全网最细

sakura的博客 3万+

麒麟银河操作系统V10部署ffmpeg(也能用于Linux系统)

部署ffmpeg用来处理视频的各种操作,如编码解码,格式转换,剪辑,处理实时视频流,音频流,加滤镜等

zhouwenxing666的博客 9035

通用(内核)链表详解

Linux内核中充斥着大量的数据结构,这些数据结构很多都是使用结构体来表示:如cdev结构体用于描述一个字符设备,再如task_struct结构体,是我们所说的进程控制块PCB,用于描述一个进程的所有信息。追寻内核源码我们会发现很多都是表示设备的结构体中都有list_head这样的字段,没错这就是内核链表的节点类型。描述设备的结构体中只要包含这个字段,内核就能通过链表来管理我们的设备,试想浩瀚的内核

LieBao 9608

【ArcGIS微课1000例】0118:一文讲清楚tif(geotiff)栅格数据格式

TIFF(Tagged Image File Format)是一种常见的图像文件格式,它被广泛用于存储和传输各种类型的图像数据。图像存储:TIFF格式可以存储多通道的位图图像,包括灰度图、彩色图和透明度图等。它支持不同的像素深度,可以是8位、16位、24位或32位等。因此,TIFF格式非常适合存储高质量的图像数据,包括照片、卫星图像、医学影像等。无损压缩:TIFF格式支持无损压缩,这意味着图像可以被压缩而无需损失任何像素信息。这种压缩方式可以减小文件大小,而不会降低图像的质量。

智慧空间实验室 2819

linux C —— 通用链表(整理自Linux内核链表)

目录 1. 简介 1.1 内核链表的思想 1.2 内核链表的技术原理: 2. 基于内核链表的通用链表 2.1 list.h 2.2 test.c 3. 内核链表 4. 文件下载 1. 简介 在Linux源代码树的include/linux/list.h文件中,采用了一种类型无关的双循环链表实现方式。其思想是将指针prev和next从具体的数据结构中提取出来构成一种通用的"...

u011285208的博客 3262

Coze智能体开发:开始使用扣子

扣子全新升级!它不仅能帮你办公、做视频、写代码,更具备自主任务执行、探索进化等能力,真正从“陪你聊”走向“帮你干活”。

王国平的博客 122

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

实现通用的双向链表(c语言实现)

国庆8天在家阅读李先静大神的书籍,抽空把一些笔记记录下来。从实现一个通用的双向链表开始。 1. 构建链表节点   链表节点存值还是存值的地址(指针)?对于通用链表首先要做到能够存放任何数据类型的数据,首先可能会想到的是union,但是数据类型无穷无尽,不可能在union中全部表示。那么可行的办法有两种:   (1) 存值 typedef struct _DListNode DLis

echo_bright_的博客 8499

深度学习工具包 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")

【数据结构】企业级!!!通用链表实现

通用链表实现:C 语言数据结构的抽象设计

qq_75261793的博客 512

visio安装包

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

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

数据结构——单向链表和双向链表的实现(C语言版)

这篇文章关于链表的介绍,还有单向链表和双向链表的C语言实现,内容干货满满,建议边看边上手敲代码!通过这篇文章,相信你已经对链表这个数据结构有了一定的了解,可以开始刷一些链表的OJ题目。如果只是看了一遍,建议上手敲敲代码,实践出真知。创作不易,希望这篇文章能给你带来启发和帮助,如果喜欢这篇文章,请留下你的三连哦,你的支持的我最大的动力!!!

2301_79171011的博客 3798

数据结构——C语言实现链表

一. 链表的概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。在这里介绍链表中的两种结构

theonly_Love的博客 1万+

[数据结构]——链表详解

数据结构---链表详解

m0_62023005的博客 4459

c语言 链表_keil实现C语言的通用双向链表

1、前言链表是数据结构中非常重要的一个知识点,比较经典的就是C语言的链表,在学校也有这门课程,非计算机专业的朋友可能没学到这一章就毕业了(呵呵),在这里可以和我一起学习。因为个人偏好对链表的知识也没有面面俱到,全面的链表知识请多方查证学习。这篇文章主要介绍一个通用双向链表,之所以叫通用因为链表本身不包含特定应用层的设计,只是将多个节点连接起来组成一条链的结构,每个节点挂载的"内容"是应用层的设计。...

weixin_39831104的博客 685

数据结构----双向循坏链表的实现(通用)

在实际情况中,基本的链表只能用于单个数据类型,为了更为方便,设计了一个通用的链表,可用于所有数据类型的储存。

2301_79944784的博客 1058

数据结构——链表

数据结构是计算机四大件之一,是与计算机组成原理、操作系统、计算机网络齐名的存在,因此数据结构的重要性不言而喻。本章将带领大家来了解链表

2302_80243065的博客 1744

【数据结构和算法】4. 链表

链表(linked list)是一种序列形的数据结构,其中包含了很多通过链接 (link) 被串起来的节点。每个节点有一个数据域,储存着节点的数值,还有一个指针域,指向下一个节点。

尊新必威的博客 1375

数据结构与算法 | 链表-4:双向链表的实现

双向链表的实现?1 前言2 Python实现2.1 先定义节点2.2 定义双链表2.3 实例参考 1 前言 关于链表的系列,目前已经整理完成了: 数据结构与算法 | 链表-1 数据结构与算法 | 链表-2:单链表的实现 数据结构与算法 | 链表-3:单向循环链表的实现 现在还剩下双向链表的问题,双向链表的结构如下: 那如何实现它呢? 2 Python实现 2.1 先定义节点 class No...

RUC_Lee的博客 838

【数据结构】链表的实现以及应用

在数据结构中,链表是重中之种,后续的树等等数据结构需要用到链表,对链表掌握熟练,就能对数据结构有更深层次的理解。本文从链表的概念及结构,以及链表的头插、尾插、头删、尾删、查询、销毁等接口函数,链表的应用等方面具体介绍了链表这个数据结构,相信对初学链表的朋友一定有所帮助!!

m0_65679465的博客 3263
上一篇: 3.数据结构之通用编程思想的引入
下一篇: 5.数据结构之通用动态数组
linux_player_c
博客等级 码龄13年 214粉丝 134原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值