线性表详解(静态链表、单链表、双向链表、循环链表)

5分钟学会数据结构中的线性链表 线性表可以说是一种最基础最简单的数据结构,它表示的是一种线性结构,比较常见的线性结构包括数组和链表等。所谓的链表,顾名思义,就是链式的线性表,即链表也是一种线性表。与数组不同的是,链表采用的是链式存储,这种链式结构是非连续、非顺序的内存空间。链表中的每一个独立的元素被称为结点,故链表由一系列的结点组成。假如我们需要存放一堆物品,但没有足够大的空间将所有的物品一次性放下,此时该如何既放下所有的物品,又能简单的找到所有的物品位置呢? 阅读详情

申明

  本文章属于原创,其中参考了程杰老师《大话数据结构》行文结构和内容,侵删。

1. 线性表的定义

  线性表(List):零个或多个数据元素的有限序列。
  这里需要强调几个关键的地方。
  首先它是一个序列。也就是说,元素之间是有顺序的,若元素存在多个,则第一个元素无前驱,最后一个元素无后继,其他每个元素都有且只有一个前驱和后继。
  然后,线性表强调是有限的,事实上,在计算机中处理的对象都是有限的,那种无限的数列,只存在于数学的概念中。

图3-2-1
  所以线性表元素的个数n(n>=0)定义为线性表的长度,当n=0时,称为空表。
  在非空表中的每个数据元素都有一个确定的位置,如a1时第一个数据元素,an时最后一个元素,ai是第i个数据元素,称i为数据元素ai在线性表中的位序。
  在较复杂的线性表中,一个数据元素可以由若干个数据项组成。

学号 姓名 性别 出生年月 家庭住址
1 张三 男 1995.3 东街西巷1号203室
2 李四 女 1994.8 北路4弄5号6室
3 王五 女 1994.12 南大道789号
… … … … …

2. 线性表的抽象数据类型

ADT 线性表(List)
Data
  线性表的数据对象集合为(a1,a2,…,an),每个元素的类型均为DataType。其中,除了第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。
Operation
  InitList(*L): 初始化操作,建立一个空的线性表L。
  ListEmpty(L): 若线性表为空,返回true,否则返回false。
  ClearList(*L): 将线性表清空。
  GetElem(L, I, *e): 将线性表L中的第I个位置元素值返回给e。
  LocateElem(L, e): 在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在表中序号表示成功;否则,返回0表示失败。
  ListInsert(*L, I, e): 在线性表L中的第I个位置插入新元素e。
  ListDelete(*L, I, *e): 删除线性表L中第I个位置元素,并用e返回其值。
  ListLength(L): 返回线性表L的元素个数。
endADT

  对于不同应用,线性表的基本操作是不同的,上述操作是最基本的,对于实际问题中涉及的关于线性表的更复杂操作,完全可以用这些基本操作的组合来实现。
  比如,要实现两个线性表A和B的并集操作。即要使得集合A=A∪B。说白了,就是把存在集合B中但不存在A中的元素插入到A中即可。
  仔细分析一下这个操作,发现我们只要循环集合B中的每个元素,判断当前元素是否存在A中,若不存在,则插入到A中即可。
  我们假设La表示集合A,Lb表示集合B,则代码实现如下:

/*将所有的在线性表Lb中但不在La中的数据元素插入到La中*/
void unionL(SqList *La,SqList Lb)
{
   
   
	int La_len,Lb_len,i;
	ElemType e;                        /*声明与La和Lb相同的数据元素e*/
	La_len=ListLength(*La);            /*求线性表的长度 */
	Lb_len=ListLength(Lb);
	for (i=1;i<=Lb_len;i++)
	{
   
   
		GetElem(Lb,i,&e);              /*取Lb中第i个数据元素赋给e*/
		if (!LocateElem(*La,e))        /*La中不存在和e相同数据元素*/
			ListInsert(La,++La_len,e); /*插入*/
	}
}

3. 线性表的顺序存储结构

3. 1 顺序存储定义

  指的是用一段地址连续的存储单元依次存储线性表的数据元素。
  线性表(a1,a2,…,an)的顺序存储示意图如下:

顺序存储示意图

3. 2 顺序存储方式

  即在内存中找一段空间,通过占位的方式,把一定的内存空间占据,然后把相同数据类型的数据元素依次放在这块空地中。既然线性表的每个数据元素的类型都相同,所以可以用C语言的**一位数组来实现顺序存储结构,**即把第一个数据元素存到数组下标为0的位置中,接着把线性表相邻的元素存储在数组中相邻的位置。
  来看线性表的顺序存储的代码。

#define MAXSIZE 20          /* 存储空间初始分配量 */
typedef int ElemType;       /* ElemType类型根据实际情况而定,这里假设为int */
typedef struct
{
   
   
    ElemType data[MAXSIZE]; /* 数组,存储数据元素 */
    int length;             /* 线性表当前长度 */
}SqList;

  这里,我们就发现描述顺序存储结构需要三个属性:
  1. 存储空间的起始位置:数组data,它的存储位置就是存储空间的存储位置。
  2. 线性表的最大存储容量:数组长度MaxSize。
  3. 线性表的当前长度: length。

3. 3 数据长度与线性表长度区别

  这里有两个概念“数组的长度”和“线性表的长度”需要区分一下。
  数组的长度是存放线性表的存储空间的长度,存储分配后这个量一般是不变的。
  线性表的长度是线性表中数据元素的个数,随着线性表的插入和删除操作的进行,这个量是变化的。
  在任意时刻,线性表的长度应该小于等于数组的长度。

3. 4 地址计算方法

  由于我们数数都是从1开始数的,线性表的定义也不能免俗,起始也是1,但是C语言中数组却是从0开始第一个下标的,于是线性表的第i个元素是要存储在数组下标为i-1的位置。
  用数组存储顺序表意味着要分配固定长度的数组空间,由于线性表中可以进行插入和删除操作,因此分配的数组空间要大于等于当前线性表的长度。
  存储器中的每个存储单元都有自己的编号,这个编号称为地址。 假设占用的是c个单元,那么线性表中第i+1个数据元素的存储位置和第i个数据元素的存储位置满足下列关系(LOC表示获得存储位置的函数)。

LOC(ai+1) = LOC(ai) + c

所以对于第i个数据元素ai的存储位置可以由a1推算得出:

LOC(ai) = LOC(a1) + (I - 1) * c

  通过这个公式,你可以随时酸楚线性表中任意位置的地址,不管它是第一个还是最后一个,都是相同的时间。那么我们对每个线性表位置的存入或者取出数据,对于计算机来说,都是相等的时间,也就是一个常数,因此我们用算法中学到的时间复杂度的概念来说,它的存取时间性能为O(1)。我们通常把具有这一特点的存储结构称为随机存取结构。

4. 顺序存储结构的插入与删除

4.1 获得元素操作

  对于线性表的顺序存储结构来说,如果我们要实现GetElem操作,即将线性表L中的第i个位置元素值返回,其实是非常简单的。就程序而言,只要i的数值在数组下标范围内,就是把数组第i-1下标的值返回即可。来看代码:

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;         /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:用e返回L中第i个数据元素的值,注意i是指位置,第1个位置的数组是从0开始 */
Status GetElem(SqList L,int i,ElemType *e)
{
   
   
    if(L.length==0 || i<1 || i>L.length)
            return ERROR;
    *e=L.data[i-1];

    return OK;
}

  注意这里返回值类型Status是一个整型,返回OK代表1,ERROR代表0。之后代码中出现就不再赘述。

4.2 插入操作

  刚才我们也谈到了,这里的时间复杂度为O(1)。我们现在来考虑,如果我们要实现ListInsert(^L,i,e),即在线性表L中的第i个位置插入新元素e,在插入数据时的实现过程如图所示。

插入示意图
  插入算法的思路:
  1. 如果插入的位置不合适,抛出异常;
  2. 如果线性表长度大于等于数组长度,则抛出异常或动态增加容量。
  3. 从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置。
  4. 将要插入元素填入位置i处。
  5. 表长加1.
  实现代码如下:

/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(SqList *L,int i,ElemType e)
{
   
    
	int k;
	if (L->length==MAXSIZE)  /* 顺序线性表已经满 */
		return ERROR;
	if (i<1 || i>L->length+1)/* 当i比第一位置小或者比最后一位置后一位置还要大时 */
		return ERROR;

	if (i<=L->length)        /* 若插入数据位置不在表尾 */
	{
   
   
		for(k=L->length-1;k>=i-1;k--)  /* 将要插入位置之后的数据元素向后移动一位 */
			L->data[k+1]=L->data[k];
	}
	L->data[i-1]=e;          /* 将新元素插入 */
	L->length++;

	return OK;
}

4.3 删除操作

  删除算法的思路:
  1. 如果删除位置不合理,抛出异常。
  2. 取出删除元素。
  3. 从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置。
  4. 表长减1.
  

数据结构——线性链表/单链表设计 在设计单链表时,我们首先要引入单链表的定义,你首先得知道它是什么? 结点:用一组任意的存储单元存储线性表的数据元素(存储单元可以是连续的,也可以是不连续的),对其中一个数据元素来说,不仅要存储其本身的信息之外没还需存储一个指示其直接后继的信息(即直接后继的存储位置),这两部分信息组成这个数据元素的存储映像,称为结点。 线性链表/单链表:结点包括两个域,存储数据元素信息的被称为数据域,存储其直接后继存储位置的域称为指针域,指针域中存储的信息称作指针/链。多个结点链接成一个链表,即为线性表的链式存储结构,. 阅读详情

相关推荐

2024年最新数据结构与算法——线性表(链表篇)_线性链表,5分钟搞定

ai+1ai+1之间的逻辑关系,对数据元素aiaiai来说,除存储其本身的信息之外,还需要存储一个指示它直接后继的信息(即直接后继的存储位置),这两部分信息组成数据元素aiaiai的存储映像,:其中存储数据元素信息的域称为数据域,存储直接后继存储位置的域称为指针域,指针域中存储的信息称为指针或链,nnn个结点(aiaiai(1

2401_84573133的博客 1194

线性表(数组、单链表、静态链表、循环链表、双向链表)

线性表的定义 线性表(List):零个或多个数据元素的有限序列。 有几个地方需要强调: 首先它是一个序列,也就是说元素之间是有顺序的,若元素存在多个,则第一个元素无前驱,最后一个元素无后继,其他每个元素都有且只有一个前驱和后继。 然后线性表强调的是有限的。 最后线性表中的数据元素必须是相同类型。 如果用数据语言来定义,可如下(配合下图理解): 数学语言定义: 若将线性表记为(a1...

cp_Mark的博客 1550

2025 高效抓取雪球社区数据:自动化导出Excel与PDF全攻略

本文详细介绍了2025年高效自动化抓取雪球社区数据的完整方案。通过Python脚本,用户可自动抓取帖子列表数据并导出为结构化的Excel表格,同时批量将帖子内容保存为PDF文档,并支持合并与添加书签,极大提升投资研究和信息整理的效率。

weixin_29034963的博客 684

【文章阅读+代码复现】Point-GNN

Brief 在3D点云语义分割方法中,GNN已经做了很多可用的方案,但是在目标检测上依旧是采用比较传统的CNN和稀疏卷积的组合,这一篇文章是研究了图卷积在3D检测的中的用法。来自卡内基梅隆大学。已经被CVPR2020接收. 这里是 paper 这里是 code Abstruct 一个采用GNN设计的3D目标检测框架 过程是先将点云场景编码成图结构,随后设计了一个叫point-GNN的网络结构,在...

有所为,有所成长 1万+

从零搭建UVM验证环境:新手入门实践指南

在数字芯片验证领域,SystemVerilog和UVM(Universal Verification Methodology)是构建高效验证环境的核心技术。其原理基于面向对象编程和事务级建模,通过组件化架构实现验证的复用性和自动化。这一方法学的技术价值在于显著提升验证效率与质量,广泛应用于处理器、通信芯片等复杂设计的验证场景。本文聚焦于UVM验证环境的搭建实践,通过一个加法器实例,详细解析了uvm_driver、uvm_monitor、uvm_sequence等关键组件的协同工作机制,并提供了基于Quest

weixin_30015371的博客 436

关于并网继电器的继电器自检逻辑及实现方式

对于常规的光伏并网逆变器来说,继电器控制至关重要。继电器一般位于逆变电感后,共模电感前,用于将逆变电压与电网电压脱开,一般国外有双继电器的安规强制认证要求,国内目前只需要单继电器要求(后续应该会有双继电器要求,个人感觉)

weixin_29982209的博客 2595

Unity 实现动态网格地图生成与交互组件

本文详细介绍了在Unity中实现动态网格地图生成与交互组件的完整方案。从基础网格单元实现到高级交互功能,涵盖网格生成器核心逻辑、事件驱动架构、性能优化技巧以及六边形网格等特殊实现。特别适合游戏开发者学习如何构建战棋、模拟经营类游戏的可交互地图系统,提升开发效率与用户体验。

weixin_29015483的博客 1059

在 SAP S/4HANA Cloud Public Edition 中掌控 ABAP 生命周期管理:One-Off、Multi-Off 与 Scalable Delivery 的落地方法论

本文系统梳理了SAP S/4HANA Cloud Public Edition中ABAP扩展开发的三种生命周期管理模式:One-Off适用于企业内部扩展,通过Import Collection在三系统间流转;Multi-Off面向少量客户交付,基于gCTS和Git实现不连接系统间的传输;Scalable Delivery则将扩展产品化为add-on,支持规模化分发。文章结合RAP、OData等实际开发场景,对比分析了各模式的特点与适用边界,为国内团队提供了符合Public Cloud要求的开发与交付实践建议

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1486

C#实现OPC客户端与S7-1200 PLC通信:工控场景稳定通信的实战指南(附完整代码)

标准化优先:OPC UA是工业通信的标准,相比直接通信,更适合多设备集成的工控场景;稳定性第一:必须封装断线重连、异常处理、资源释放逻辑,满足7×24小时运行需求;效率优化:高频采集场景优先用批量读写,避免单个变量频繁请求;细节把控:节点ID、变量类型、端口配置等细节是新手最容易踩坑的地方,建议先用UA Expert验证。这套代码和方案已在多个工业项目中落地,从单台S7-1200到多台S7-1200/1500集群,都能稳定运行。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1019

allegro如何设置走线等长

设置走线等长!

weixin_42499230的博客 6916

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

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

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Camera2Demo

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

上一篇: 算法知识绪论
下一篇: 项目管理综述
x小悠
博客等级 码龄12年 36粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值