[数据结构]双向链表(C语言)

双向链表

双向链表概念

双向链表也叫双链表,其每个数据结点中都有两个指针,分别指向直接后继和直接前驱。在单向链表中若要找到某个节点的前驱节点,需要先遍历到这个节点,然后再遍历一次找到其前驱节点,这无疑是十分低效的。而双向链表可以做到正向反向遍历,由此相比单向链表可以更高效地找到某个节点的前驱节点。



双向链表的创建

双向链表的节点构成

双向链表的单个节点含有两个指针域,一个值域。

结构体

typedef int Elemtype;

typedef struct Node {

    Elemtype data;
    struct Node *prior;      //前驱指针
    struct Node *next;       //后驱指针

} Duplist;

双向链表的初始化创建

双向链表基本上就是在单向链表的基础上多了一个前驱指针,用类似的方式建立每个节点与前驱之间关系就可以了?。
创建初始双向链表一般都是在链表尾部插入新节点:
(1)将 endnext 指向新节点 node;
(2)将 nodeprior 指向 end

双向链表图

双向链表创建代码

//创建初始化双向链表(头节点有数据,便于表头插入)
Duplist* Create_DuplexLinklist(Duplist *head, int n) {
    head = (Duplist*)malloc(sizeof(Duplist));
    head->next = NULL;
    head->prior = NULL;            
    Duplist *end = head;                       

    printf("创建双向链表输入 %d 个数据: ", n);
    scanf("%d", &head->data);
    for (int i = 1; i < n; i++) {
	Duplist *node = (Duplist *)malloc(sizeof(Duplist));
	node->prior = NULL;
	node->next = NULL;
	scanf("%d", &node->data);

	end->next = node;                      //end的next指向新节点node
	node->prior = end;                     //新节点node的前驱prior指向之前的end
	end = node;                            //end指向最后的node节点
    }
    return head;
}


双向链表的插入操作

双向链表的插入分为三种,分别为表头插入,表中插入和表尾插入。

表头插入

表头插入操作(这里顺序无所谓):

(1)将 headprior 指向新节点 node;
(2)将 nodenext 指向 head
(3)将 head 指向新节点 node

表头插入图解

表中插入

表中插入操作(这里的顺序不能轻易改变,画图有助于理解):

找到插入位置处pos之前的节点 t;
(1)将 tnextprior 指向新节点 node;
(2)将 nodenext 指向 tnext;
(3)将 tnext 指向新节点 node;
(4)将 nodeprior 指向 t

表中插入图解

表尾插入

表尾插入操作:

(1)将 endnext 指向新节点 node;
(2)将 nodeprior 指向 end;
(3)将 end 指向新节点 node

表尾插入图解

双向链表插入操作代码

//插入新节点(包含三种情况 头插 尾插 和 指定位置插入)
Duplist *Insert_DuplexLinklist(Duplist *head, int pos, int data) {
	Duplist *node = (Duplist *)malloc(sizeof(Duplist));
	node->data = data;
	node->prior = NULL;
	node->next = NULL;
	//pos表示要插入的位置(head为1)
	if (pos == 1) {                       //插在链表头的情况
		node->next = head;                //新节点node的next指向之前的头head
		head->prior = node;               //之前的head的前驱prior指向了node
		head = node;                      //head重新指向了插在表头的新节点
	} else {
		Duplist *t = head;                //t为遍历指针
		for (int i = 1; i < pos - 1; i++) //t指向要插入位置的前一个节点
			t = t->next;

		if (t->next == NULL) {            //插在链表尾的情况
			t->next = node;               //t指向表尾,t的next指向新节点node
			node->prior = t;              //新节点node的前驱prior指向t
		} else {
			//插在表中的情况
			t->next->prior = node;        //t的下一个节点(要代替位置的节点)的前驱指向新node
			node->next = t->next;         //新node的next指向了之前t的下一个节点
			t->next = node;               //t的next重新指向新node
			node->prior = t;              //node前驱prior指向了t
		}
	}

	return head;
}


双向链表的删除操作

双向链表删除节点也可以分成三种,表头删除、表中删除和表尾删除。

表头删除

表头删除操作:

(1)head 后移;
(2)此时的 headprior 置NULL。
操作比较简单就省略图解了?

表中删除

表中删除操作:

(1)tpriornext 指向 tnext
(2)tnextprior 指向 tprior

表中删除图解

表尾删除

表尾删除操作

如果 t 指向表尾
(1)直接将此时 tpriornext 置 NULL。
操作比较简单就省略图解了?

双向链表删除操作代码

//删除指定位置节点
Duplist* Delete_DuplexLinklist(Duplist *head, int pos) {
	Duplist *t = head;
	for (int i = 1; i < pos; i++)
		t = t->next;                  //找到要删除的节点

	if (t != NULL) {
		if (t->prior == NULL) {       //如果是头节点
			head = t->next;           //head往后移
			free(t);
			head->prior = NULL;
			return head;
		} else if (t->next == NULL) { //如果是尾节点
			t->prior->next = NULL;    //表尾的前一个节点的next置NULL
			free(t);
			return head;
		} else {                      //删除表中节点的情况
			t->prior->next = t->next; //要删除节点的前一个节点的next跨越直接指向下下个节点
			t->next->prior = t->prior;//要删除节点的后一个节点的prior跨越指向上上个节点
			free(t);
			return head;
		}
	} else
		printf("节点不存在\n");

    return head;
}


双向链表测试代码(附带其他操作)

源代码

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

typedef int Elemtype;

typedef struct Node {

	Elemtype data;
	struct Node *prior;      //前驱指针
	struct Node *next;       //后驱指针

} Duplist;

//创建初始化双向链表(头节点有数据,便于表头插入,要与单向链表区分)
Duplist *Create_DuplexLinklist(Duplist *head, int n) {
	head = (Duplist*)malloc(sizeof(Duplist));
	head->next = NULL;
	head->prior = NULL;            
	Duplist *end = head;                       //用于在尾部插入新节点

	printf("创建双向链表输入 %d 个数据: ", n);
	scanf("%d", &head->data);
	for (int i = 1; i < n; i++) {
		Duplist *node = (Duplist *)malloc(sizeof(Duplist));
		node->prior = NULL;
		node->next = NULL;
		scanf("%d", &node->data);

		end->next = node;                      //之前的end的next指向新节点node
		node->prior = end;                     //新节点node的前驱prior指向之前的end
		end = node;                            //end永远指向最后的node节点
	}

	return head;
}

//插入新节点(包含三种情况 头插 尾插 和 指定位置插入)
Duplist *Insert_DuplexLinklist(Duplist *head, int pos, int data) {
	Duplist *node = (Duplist *)malloc(sizeof(Duplist));
	node->data = data;
	node->prior = NULL;
	node->next = NULL;
	//pos表示要插入的位置(head为1)
	if (pos == 1) {                       //插在链表头的情况
		node->next = head;                //新节点node的next指向之前的头head
		head->prior = node;               //之前的head的前驱prior指向了node
		head = node;                      //head重新指向了插在表头的新节点
	} else {
		Duplist *t = head;                //t为遍历指针
		for (int i = 1; i < pos - 1; i++) //t指向要插入位置的前一个节点
			t = t->next;

		if (t->next == NULL) {            //插在链表尾的情况
			t->next = node;               //t指向表尾,t的next指向新节点node
			node->prior = t;              //新节点node的前驱prior指向t
		} else {
			//插在表中的情况
			t->next->prior = node;        //t的下一个节点(要代替位置的节点)的前驱指向新node
			node->next = t->next;         //新node的next指向了之前t的下一个节点
			t->next = node;               //t的next重新指向新node
			node->prior = t;              //node前驱prior指向了t
		}
	}

	return head;
}

//删除指定位置节点
Duplist* Delete_DuplexLinklist(Duplist *head, int pos) {
	Duplist *t = head;
	for (int i = 1; i < pos; i++)
		t = t->next;                  //找到要删除的节点

	if (t != NULL) {
		if (t->prior == NULL) {       //如果是头节点
			head = t->next;           //head往后移
			free(t);
			head->prior = NULL;
			return head;
		} else if (t->next == NULL) { //如果是尾节点
			t->prior->next = NULL;    //表尾的前一个节点的next置NULL
			free(t);
			return head;
		} else {                      //删除表中节点的情况
			t->prior->next = t->next; //要删除节点的前一个节点的next跨越直接指向下下个节点
			t->next->prior = t->prior;//要删除节点的后一个节点的prior跨越指向上上个节点
			free(t);
			return head;
		}
	} else
		printf("节点不存在\n");

    return head;
}

//读取单个数据
void Read_DuplexLinklist(Duplist *head, int pos) {
	Duplist *t = head;
	for (int i = 1; i < pos; i++)
		t = t->next;

	if (t != NULL)
		printf("第 %d 个位置的数据为 %d", pos, t->data);
	else
		puts("节点不存在");
}

//改变指定位置数据
Duplist* Change_DuplexLinklist(Duplist *head, int pos, int data){
	Duplist *t = head;
	for(int i = 1; i < pos; i++)
		t = t->next;

	if(t != NULL)
		t->data = data;
	else
		puts("节点不存在");

	return head;
}

//查找数据返回下标
int Find_DuplexLinklist(Duplist *head, int n) {
	Duplist *t = head;
	int pos = 1;
	while (t != NULL) {
		if (t->data == n) {
			printf("该数据的位置为 %d", pos);
		}
		t = t->next;
		pos++;
	}
	return -1;
}

//遍历打印双向链表
void Show_DuplexLinklist(Duplist *head) {
	Duplist *t = head;
	while (t != NULL) {
		printf("%d ", t->data);
		t = t->next;
	}
	printf("\n");
}

//反向打印双向链表  
void Reverse_DuplexLinklist(Duplist *head){
	Duplist *t = head;
	while (t->next != NULL)           //指向最后一个节点
		t = t->next;

	while (t != NULL)
	{
		printf("%d ",t->data);
		t = t->prior;
	}
	printf("\n");
}

int main() {
	Duplist *mylist = NULL; 

	mylist = Create_DuplexLinklist(mylist, 10);
	puts("初始状态双向链表:");
	Show_DuplexLinklist(mylist);
	printf("\n");

    mylist = Insert_DuplexLinklist(mylist, 11, 30);
	mylist = Insert_DuplexLinklist(mylist, 1, 30);
	puts("在头和尾 的位置插入数据30后:");
	Show_DuplexLinklist(mylist);
	printf("\n");

	mylist = Change_DuplexLinklist(mylist,5,22);
	puts("改变第 5 的位置数据为 22 后:");
	Show_DuplexLinklist(mylist);
	printf("\n");

	mylist = Delete_DuplexLinklist(mylist, 8);
	mylist = Delete_DuplexLinklist(mylist, 1);
	puts("删除第 1 和 8 的位置数据后:");
	Show_DuplexLinklist(mylist);
	printf("\n");

	puts("双向链表反向输出:");
	Reverse_DuplexLinklist(mylist);
	printf("\n");

	return 0;
}

测试结果

一切都是命运石之门的选择,本文章来源于博客园,作者:Amαdeus,出处:http://www.cnblogs.com/MAKISE004/p/17058633.html,未经允许严禁转载

本文转载于网络 如有侵权请联系删除

相关文章

  • 秒激活IDEA,最新永久idea激活码,2022 idea 激活码分享

    IDEA最新永久2022激活码(秒激活)img为什么说秒激活呢,因为不需要像网上大多的激活教程,又是这个操作又是那个操作的。真正的一秒激活IDEA激活码获取链接:点击获取最新idea激活码IDEA激活码获取链接:点击获取最新idea激活码IDEA激活码获取链接:点击获取最新idea激活码imgIDEA一键生成方法的序列图序列图(SequenceDiagram),亦称为循序图,是一种UML行为图。表示系统执行某个方法/操作(如登录操作)时,对象之间的顺序调用关系。这个顺序调用关系可以这样理解:你需要执行系统中某个对象a提供的方法/操作login(登录),但是这个对象又依赖了对象b提供的方法getUser(获取用户)。因此,这里就有了a->b调用关系之说。我们可以通过SequenceDiagram这个插件一键生成方法的序列图。如果你因为网络问题没办法使用IDEA自带的插件市场的话,也可以通过IDEA插件市场的官网手动下载安装。图片如何使用呢?1、选中方法名(注意不要选类名),然后点击鼠标右键,选择SequenceDiagram选项即可!图片2、配置生成的序列图的一些基本的参数比如调用

  • okio源码解析「建议收藏」

    大家好,又见面了,我是你们的朋友全栈君。1、为什么要学习okio源码?a)okio是安卓大神JakeWharton之作,大神之作必须是值得学习的。b)okio简单易用,高效。okio是对Javaio、nio的简洁封装,原生的Javaio采用装饰者模式,使用的时候非常繁琐,而相同的操作okio只需短短几行代码就可以搞定,当然除了简单易用之外,okio还是一个非常高效的io库,显著的节省CPU和Memory资源。c)okio是okhttp的io组件。现在okhttp已经被Google采纳,作为Android默认的通信组件,这么牛的io组件难道不值得一学吗?2、概述2.1整体结构上图是okio的整体结构,可以看到整个okio分为四个重要部分,sink(输出,可以理解为是Java中的OutputStream的代理,最终通过OutputStream将byte写入文件等)、Source(输入,可以理解为是Java中的InputStream的代理,最终通过InputStream读取字节)、Timeout是okio中加入的超时机制、SegmentPool是okio中的Segment池,和一般的池的作用

  • 一鸣惊人!华中科大管理学院本科学子勇夺国际供应链建模设计大赛特等奖

    x华中科大管理学院本科学子勇夺国际供应链建模设计大赛【特等奖】NEWS2022年5月29日,第二届国际供应链建模设计大赛落下帷幕,华中科技大学管理学院代表队(以下称为“华科管理队”)在激烈的竞赛中脱颖而出,荣获特等奖,团队指导老师为华中科技大学管理学院管理科学与信息管理系秦虎教授。本届国际供应链建模设计大赛是由中国交通运输协会、全国交通运输职业教育教学指导主办,北京络捷斯特科技发展股份有限公司提供技术支持。本次大赛分挑战赛、精英赛-本科组、精英赛-高职组三个组别进行,共有来自全国316所院校的536个团队报名参赛。其中,挑战赛面向中国国内著名985、211和双一流大学以及国际知名院校的本科生团队,华科管理队凭借全面、完善的分析与精益求精的方案设计体系,通过沉着冷静、思路清晰的答辩,从问题分析和解决方案的完整性、科学性、创新性、准确性、规范性和实用价值等方面通过了各大评委的层层考验,最终在决赛的挑战赛赛道中斩获特等奖。 详细的获奖信息如下: 第二届国际供应链建模设计大赛决赛获奖名单公布 华科管理队由华中科技大学管理学院不同专业的5名本科生组成,分别是:胡心瑶华中科技大学管理学院信息管理

  • 浅析前端模块化

    CommonjsCommonjs是以在浏览器环境外构建JavaScript生态系统为目标而产生的项目,比如在服务器或桌面环境中。//Commonjs是通过module.exports导出对外的变量或接口, //通过require()来导入其他模块的输出到当前模块作用域中。 //a.js module.exports={a:'hello'} //b.js constb=require(./a); console.log(b.a) 复制Commonjs是「同步加载模块」,是「服务端模块化的规范」,Nodejs是基于Commonjs规范实现的。AMDAMD是异步定义模块,也是使用require()语句加载模块,但是它需要接收两个参数:require([module],callback)//需要加载的模块,加载完成之后的回调 复制AMD制定了客户端模块化的规范,Requeirejs基于AMD实现。UMDUMD是Commonjs和AMD的糅合,UMD先判断是否支持Node.js的模块(exports),存在则使用Node.js模块模式;再判断是否支持AMD(define)

  • Android ViewPager2 真的香么?

    Google前段时间出了新品ViewPager2,据说意在替代旧版ViewPager,功能更强大使用更方便;真的这么香么,和尚尝试学习一下!优势支持RTL布局,稍后介绍;支持垂直方向切换;支持Fragment集合刷新,即notifyDataSetChanged;版本ViewPager2目前处于预览版,还没有合并到主分支,可能还会有一些隐藏小问题,建议大家先尝试一下;implementation'androidx.viewpager2:viewpager2:1.0.0-alpha02' 复制问题和尚尝试第一步要引入ViewPager2,而此时就出现一个大问题,如下:和尚当前SDK已是最新版本,首先按照提示在AndroidManifest->application添加错误中要求的,但是并不能解决问题,之后查阅了很多资料,发现Androidx与Androidsupport库不共存,这可真是麻烦了,如果在实际的项目中直接用可麻烦大了;解决既然不兼容,只好先转到Androidx库下,chenzhenlindx大神的博客很有帮助;工程->Refactor->M

  • 一周好文推荐

    微信公众号除了服务号以外,都不支持外部链接,建议读者复制链接在浏览器打开。 实现灾备的几种办法 https://www.cockroachlabs.com/blog/why-do-database-outages-happen/建立良好的团队文化,文中给出了几种有趣的办法 https://queue.acm.org/detail.cfm?ref=rss&id=3323993Python中pip的详细介绍 https://realpython.com/what-is-pip/PEP570(Positional-OnlyParameters)被接受了,引入新的语法/ https://www.python.org/dev/peps/pep-0570/Pythonlru方法不建议使用装饰器方式,而是本地函数,避免全局缓存。 https://orbifold.xyz/local-lru.html管理Python包环境 https://wkulikowski.com/2019/programming-environments/StreamingSQL入门 https://wso2.com/

  • 配置MySQL主从/双主引发的反思 原

    记一次mysql配置双主全过程[danger]强烈建议在执行本节所有操作前将所有操作命令操作copy到SublimeText编辑器替换port为要配置主从的mysql实例对应的端口,避免误操作!!! [danger]强烈建议在执行本节所有操作前将所有操作命令操作copy到SublimeText编辑器替换port为要配置主从的mysql实例对应的端口,避免误操作!!! [danger]强烈建议在执行本节所有操作前将所有操作命令操作copy到SublimeText编辑器替换port为要配置主从的mysql实例对应的端口,避免误操作!!! 备份主库数据使用innobackupex工具进行备份(因本次涉及到的数据库实例较多,所以编写shell脚本,减少出错,单实例同样适用):#!/bin/bash #ports='331233133315' port=3314#单实例时手动指定数据库port #for循环和if判断只在多实例时使用 #forportin$ports;do #if[$port="3313"];then #passwd='aa

  • 基于D3.js实现分类多标签的Tree型结构可视化

    全文共5270个字,4张图,预计阅读时间25分钟。关键词:可视化,D3.js,python,前端,代码why今天新来的实习生需要对部分分类文本进行多标签的检测,即根据已构建好的一、二级标签Excel文档,对众包平台人工标注的数据以及机器标注的数据进行评测。 此情此景,让我想起了曾经在实验做的文本多标签分类的工作,所以就想用Echart或D3.js实现层级标签可视化为一个Tree的结构,方便实习生们查阅,提高工作效率。 说干就干!How处理数据首先,找一个标准的基于D3.js实例程序,明确一下我们的工作目标以及步骤[数据的格式+前端代码]。 看一下需要将我们目前的结构化数据:体育,篮球,NBA 体育,篮球,CNA 体育,篮球,CUBA 体育,足球,中超 体育,足球,欧冠 体育,羽毛球 体育,羽毛球,汤姆斯杯 数码,手机,iPhone 数码,手机,小米 数码,电脑,MacPro 数码,电脑,Dell 数码,电脑,小米 数码,照相机,索尼 数码,照相机,尼康 教育,大学,高数 教育,大学,英语 教育,高中,物理 教育,高中,化学 教育,高中,生物 教育,小学 教育,幼儿复制标准的可以被D3.

  • Hadoop学习笔记—18.Sqoop框架学习

    一、Sqoop基础:连接关系型数据库与Hadoop的桥梁1.1Sqoop的基本概念    Hadoop正成为企业用于大数据分析的最热门选择,但想将你的数据移植过去并不容易。ApacheSqoop正在加紧帮助客户将重要数据从数据库移到Hadoop。随着Hadoop和关系型数据库之间的数据移动渐渐变成一个标准的流程,云管理员们能够利用Sqoop的并行批量数据加载能力来简化这一流程,降低编写自定义数据加载脚本的需求。ApacheSqoop(SQL-to-Hadoop)项目旨在协助RDBMS与Hadoop之间进行高效的大数据交流。用户可以在Sqoop的帮助下,轻松地把关系型数据库的数据导入到Hadoop与其相关的系统(如HBase和Hive)中;同时也可以把数据从Hadoop系统里抽取并导出到关系型数据库里。因此,可以说Sqoop就是一个桥梁,连接了关系型数据库与Hadoop。1.2Sqoop的基本机制  Sqoop中一大亮点就是可以通过hadoop的mapreduce把数据从关系型数据库中导入数据到HDFS。Sqoop架构非常简单,其整合了Hive、Hbase和Oozie,通过map-red

  • Android wifi上网跟4G上网的区别

    手机上网可以用Wifi,也可以用4G,这两者究竟有什么区别,Wifi模块跟4G无限通信模块用的是同一种上网媒介吗,一个4G手机是否两块网卡呢?手机的MAC地址说的是谁的呢,比如,当你通过系统API获取MAC地址的时候,获取的是哪种MAC地址呢?本文由MAC地址(作为设备唯一标识)问题引出,简单分析下两种上网方式的区别,扫盲,高手勿拍砖:Wifi上网跟4G上网用的是同一块“网卡”吗Wifi上网跟4G上网的“MAC”地址是同一个吗两者在实现方式上有什么不同呢(TCP/IP协议)首先来看第一个问题,Wifi上网跟4G上网用的是同一块“网卡”吗,答案是否定的,一般而言,Wifi上网用的是以太网卡,拥有48位唯一的MAC地址,而4G上网则通过手机内部的基带模块来实现无线上网的目的。手机Wifi上网跟4G上网硬件设施的区别从硬件环境上来说,手机链接一个无线路由器,通过Wifi上网,走的还是以太网,在链路层,用的是以太网协议,也就是说,这种上网模式完全可以看做是手机连接了一根网线,所以其媒介仍可以看做传统意义上的网卡:手机wifi上网模型.png而4G上网用的是蜂窝网络,信号以电磁波的形式在空气中进

  • linux学习第四十一篇:配置防盗链,访问控制Directory,访问控制FilesMatch

    配置防盗链防盗链,就是不让别人盗用你网站上的资源,这个资源,通常指的是图片,视频,歌曲,文档等。不是我们认识的referer一概不许访问。 防盗链的作用是,我们网站的图片,只能通过我们自己的网站去访问,其他网站借用不行。 我举的例子,意思是我们的网站,被用户上传了很多图片,而用户又在他自己的网站上加上了我们网站图片的链接,就直接能访问了。 这样可以节省他网站的带宽。通过限制referer来实现防盗链的功能 配置文件增加如下内容<Directory/data/wwwroot/111.com> SetEnvIfNoCaseReferer"http://111.com"local_ref//设置referer的白名单 SetEnvIfNoCaseReferer"http://aaa.com"local_ref SetEnvIfNoCaseReferer"^$"local_ref//空referer,可以直接访问网站的图片, //如果没有这行,想要访问网站图片就需要通过上面的白名单referer去访问 <filesm

  • 腾讯云事件总线数据结构

    APIGWParamsAPIGWParams描述 被如下接口引用:CreateConnection,ListConnections。 名称 类型 必选 描述 Protocol String 是 HTTPS Method String 是 POST CkafkaDeliveryParams用来描述需要投递到kafkatopic的参数 被如下接口引用:ListRules。 名称 类型 必选 描述 TopicName String 是 ckafkatopicname ResourceDescription String 是 ckafka资源qcs六段式 CkafkaParamsCkafka连接器参数 被如下接口引用:CreateConnection,ListConnections。 名称 类型 必选 描述 Offset String 是 kafkaoffset TopicName String 是 ckafkatopic CkafkaTargetParams用来描述ckafka投递目标 被如下接口引用:CreateTarget。

  • 注释是恶魔,请不要再写一行注释

    你可以从你们现在项目里面随便找几处注释,看看写注释的代码是不是存在如下两种毛病之一: 1.命名不准确; 2.方法太长(超过50行)。   如果你找到的代码没有出现上面两种毛病而注释依然存在,那你再看看这个注释是否有实际意义,是不是这个注释不要也无所谓呢。   注释是恶魔 这个观点可能你第一次看到,你可能很难接受,因为写了这么多年的注释,你从未想过注释居然是恶魔,所以,你看到这个观点的时候可能就会本能的找出1000种理由反对(绝对不可能实现啊什么的),但是,这个观点并不是今天才出现,相信很多年前就有人提出,现在已被越来越多的人认可。   我第一次接受到这个观点还是从一个美国客户(十几年编程经验的技术大牛)那里,2011年,他让我们不要写注释。他当时主要意思是我们写的中式英语他猜起来太费劲,所以他后面又安慰我们说“好的代码是不需要注释的”,而我从此就将他后面那半句话奉为至宝。   注释是恶魔,它将我们的代码变得很难理解。就像本文开篇说的,你可以找找你们项目中出现注释的地方,要么命名不准确,要么方法太长。你可以随机找10处注释,看看有几处是恶魔,欢迎贴

  • Uni-app usingComponents 和自定义导航用法

    { "pages":[{ "path":"pages/main/main", "style":{ "navigationStyle":"custom", "transparentTitle":"auto", "titlePenetrate":"YES", "navigationBarBackgroundColor":"#0067FF", "navigationBarTextStyle":"white", "navigationBarTitleText":"", "usingComponents":{ "home-page":"/pages/main/tabs/home/home", "client-page":"/pages/main/tabs/business/business", "me-page":"/pages/main/tabs/me/me" } } },{ "path":"pages/main/tabs/home/home", "style":{ "usingComponents":{ "cb-page":"/pages/main/tabs/home/cb/cb" } }

  • 开启SAP S/4HANA升级迁移之旅-详细攻略

    https://www.sap.cn/documents/2019/12/5e92b456-777d-0010-87a3-c30de2ffd8ff.html 复制    从SAPECC迁移至SAPS/4HANA https://www.sap.cn/products/s4hana-movement.html                     有关从SAPECC迁移至SAPS/4HANA的常见问题   常见问题 为什么SAPS/4HANA只在SAPHANA数据库上运行? 只有SAPHANA列式内存数据库能够为客户提供所需的简化的数据模型,帮助他们改进业务流程、简化架构,并赢得竞争优势。     SAPHANA的成熟度如何? SAPHANA问世已有10年之久,目前在全球拥有数万家客户。数千家客户采用了基于SAPHANA内存数据库运行的SAPS/4HANA生产系统。  

  • linux-CenOS修复内核或修改内核系统启动顺序

    场景:内核update后,启动失败。 尝试修复失败: 参考1:http://www.cjcheema.com/2019/06/how-to-recover-or-rebuild-initramfs-in-centos-7-linux/(首要参考) 参考2:https://vlinux-freak.blogspot.com/2019/04/recover-or-restore-initramfs-file-in.html 问题:没有找到内核启动ISO;修复失败。 无奈方法:使用升级前的内核 参考:https://www.cnblogs.com/cnsong/p/7058000.html 参考:https://www.cnblogs.com/anliven/p/7944842.html 1.启动系统顺序,选择recue对应项目 2.修改默认启动顺序 3.使用默认系统登录后,删除失败内核包 4.系统启动后,启动列表中不显示失败内核清单  

  • [题解]luogu_P3523(树上覆盖

      #include<bits/stdc++.h> usingnamespacestd; constintmaxn=700006; intn,m; structnode{ intv,nxt; }e[maxn<<1]; inthead[maxn],cnt; inlinevoidadd(intu,intv){ e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt; } intf[maxn],g[maxn];//x子树内距离最远未被覆盖的和最近已选的 intw[maxn],ans; voiddfs(intx,intfa,intk){ for(inti=head[x];i;i=e[i].nxt){ inty=e[i].v; if(y==fa)continue; dfs(y,x,k); f[x]=max(f[x],f[y]+1); g[x]=min(g[x],g[y]+1); } if(w[x]&&g[x]>k)f[x]=max(f[x],0);//是关键点并且未被覆盖更新f,表示有点没有被覆盖 if(g

  • 建议收藏:ionic常用的命令

    安装ionic npminstall-gionic复制 更新www/lib/ionic目录的文件,如有项目中有bower,此命令会运行bowerupdateionic,否则则会从CDN上下载文件并替换。  ioniclibupdate复制 创建一个项目,其中template可以是内置的模板类型:blank/sidemenu/tabs(default)三种,也可以是github地址 (这叫ionoic-starter),或者是Codepenstarter地址 可选的参数:-ayour_app_name-icom.yourcompany.youapp-w(不要用cordova)  ionicstartyour_app_name[template]复制 启动一个本地的server,在浏览器中打开,并可监视文件变化,随时刷新浏览器。  ionicserve[options]复制 在浏览器中打开ios和andriod的显示界面  ionicserve--

  • blender 学习

    学习资料 https://www.bilibili.com/video/BV1Ji4y1g7Kf   常用快捷键 旋转平移操作 鼠标中键 旋转 alt+鼠标中键 每隔45度旋转 shift+鼠标中键 平移   模型操作 shift+a 添加新物体   按住shift选择两个点,然后按F就可以画一条直线     导出的时候   才能和meshlab中的坐标系保持一致  

  • Python:接口框架:数据驱动和代码驱动

    驱动:1、数据驱动:用例是通过数据驱动的;比如python文件需要从yaml文件里取数据,没有yaml文件就运行不了py文件2、代码驱动:用例是通过代码实现的,没有数据文件例一:数据驱动:importunittestimportddtimportrequests,nnreport@ddt.ddt#首先需要在类上面加上这个装饰器classLogin(unittest.TestCase):@ddt.file_data(r'/Users/houning/Downloads/接口自动化课程/课堂练习/课上练习/UTP/data/login.yaml')#把同级目录下的a.yaml文件的数据拿过来参数化deftest_interface(self,**test_data):#test_data代表每一个用例数据的字典#**意思是入参是个字典url=test_data.get('url')method=test_data.get('method').upper()detail=test_data.get('detail','没写用例描述')#get不到,就默认取'没写用例描述'值self._tes

  • 易基因|RNA m7G甲基化测序(m7G-MeRIP-seq)

    N7-甲基鸟苷(N7-methylguanosine,m7G)是真核生物tRNA、rRNA和mRNA5'cap中最丰富的修饰之一。作为一种重要的表观遗传修饰,m7GRNA甲基化在基因表达、加工代谢、蛋白质合成、转录稳定等方面发挥着重要的作用,参与疾病发生发展等多种生命过程。 对于m7GRNA甲基化修饰的检测,易基因采用基于抗体富集的m7G-MeRIP-seq,利用m7G特异性抗体富集发生m7G甲基化修饰的RNA片段(包括mRNA、lncRNA等rRNA去除所有RNA),结合高通量测序,对RNA上的m7G修饰进行定位与定量,总RNA起始量可降低至10μg,最低仅需1μg总RNA。   技术优势: 起始量低:样本起始量可降低至10-20μg,最低仅需1μg总RNA; 高通量测序:全转录组m7G位点高通量测序,可同时检测mRNA和lncRNA; 样本要求:可用于动物、植物、细胞及组织的m7G检测; 重复性高:m7G-MeRIP-seq的IP富集重复性高,最大化降低抗体富集偏差; 应用范围广:广泛应用于组织发育、干细胞自我更新和分化、热休克或DNA损伤应答、癌症的发生与发展、药物应

相关推荐

推荐阅读