指针

数据结构(二) -- 数组和链表

一曲冷凌霜 提交于 2020-02-13 14:04:37
/*--> */ /*--> */ /*--> */ /*--> */ 数据结构(二) -- 数组和链表 数据结构主要可以分为两大模块: 线性结构 非线性结构 本文主要开始讲线性结构。 什么是线性结构 线性结构,顾名思义,就是这些数据所有节点都能被一根线(指针)联系起来的一种结构。 线性结构的存储方式: 连续存储:【数组】 离散存储:【链表】 线性结构的常见应用方式: 栈 队列 专题 :【递归】 数组和链表 本小节学习数组和链表,从底层去了解和实现数组与链表,并分析两者对应的优缺点 数组 数组是最常见的链式存储结构,它是一段连续的内存空间,在内存中我们可以简单表示为下图样式 通过上图我们可以把代码中 int arr[6] = {1,2,3,4,5,6}; 执行的操作从内存中脑补出来,同时我们可以简单分析一下,数组应该有的一些基本使用。如 初始化、 添加新元素、 插入新元素、 删除某个元素、 判断是否为空数组、 是否是满数组、 排序 倒序 查询是否包含某个元素 ······ 本小节就带着你手把手实现一个简单的数组的封装,借此来了解数组的数据结构以及内部的一些基本算法知识。这里就简单的以一个 int 类型的数组来示例,后面学到泛型的时候便可更加好的理解数组的实现。 首先简单分析一下数组中基本的属性,我们有上面的数组内存中的逻辑图可以确定数组有对应的内存空间,有一个内存起始地址

数据结构一:链表(linux链表)

邮差的信 提交于 2020-02-13 11:25:00
一:实现机制 linux链表实现思想就是:结点里面只创建一个next指针,用指针将各个结点相连接 打印和查找的时候,再进行类型的转换 二:代码 1 LinkList.h /* LinkList.h linux链表实现思想就是:结点里面只创建一个next指针,用指针将各个结点相连接 打印和查找的时候,在进行类型的转换 */ # ifndef _LINKLIST_H_ # define _LINKLIST_H_ # include <stdlib.h> # include <stdio.h> //链表小结点 和普通链表相比较 没有数据域 只有next指针 typedef struct LINNODE { struct LINNODE * next ; } Link_Node ; //链表,有头结点和长度 typedef struct LINKLIST { Link_Node head ; // Link_Node的结构体,而不是结构体指针 int size ; //结点个数 } Link_List ; //查找回调函数 typedef int ( * FIND ) ( Link_Node * data1 , Link_Node * data2 ) ; //打印回调函数 typedef void ( * PRINT ) ( Link_Node * data ) ; //初始化 Link

c++之智能指针,异常处理,枚举

拈花ヽ惹草 提交于 2020-02-13 11:15:32
智能指针,文件IO 二、智能指针&动态内存 1. 指针潜在问题 c++ 把内存的控制权对程序员开放,让程序显式的控制内存,这样能够快速的定位到占用的内存,完成释放的工作。但是此举经常会引发一些问题,比如忘记释放内存。由于内存没有得到及时的回收、重复利用,所以在一些c++程序中,常会遇到程序突然退出、占用内存越来越多,最后不得不选择重启来恢复。造成这些现象的原因可以归纳为下面几种情况: 野指针: 内存已经被释放、但是指针仍然指向它。这时内存有可能被系统重新分配给程序使用,从而会导致无法估计的错误 重复释放:程序试图释放已经释放过的内存,或者释放已经被重新分配过的内存,就会导致重复释放错误. 内存泄漏: 不再使用的内存,并没有释放,或者忘记释放,导致内存没有得到回收利用。 忘记调用delete 随着多线程程序的广泛使用,为了避免出现上述问题,c++提供了智能指针,并且c++11对c++98版本的智能指针进行了修改,以应对实际的应用需求。 2. 智能指针 在98版本提供的 auto_ptr 在 c++11得到删除,原因是拷贝是返回左值、不能调用delete[] 等。 c++11标准改用 unique_ptr | shared_ptr | weak_ptr 等指针来自动回收堆中分配的内存。智能指针的用法和原始指针用法一样,只是它多了些释放回收的机制罢了。 智能指针位于 头文件中

C和指针---读书笔记。

烂漫一生 提交于 2020-02-13 09:24:45
C和指针---读书笔记。 1,unsigned int 声明无符号int类型 默认是 singned,即此整数类型包括正负数。也可用于long上。 说明符有 unsigned signed short long 2,枚举 enum jump{cpu = 100, a = 2}; 3,for 循环的执行顺序,,for( expression1; expression2, expression3){statement;} expression1->expression2->statement->expression3->expression2->statement->expression3->.....重复此过程直到不满足条件。 4,C中的 switch(expression){statement},expression只能是整数。 5,goto,,可以跳出多组循环,break不可以。 6,C里面 ,if(i) i 必须是int或float类型,除0外其他数值都为真。 7,所谓短路求值就是 expression1 && expression2,如果expression1为假,则不执行expression2,同理 expression1 || expression2,如果expression1 为真,则表达式为真,不执行expression2

刷题--双指针(2)

痴心易碎 提交于 2020-02-13 07:30:33
相向双指针的第二种题型: Partition array 基本题型:将一个数组根据某个条件分割,比如大于target,奇偶等等 例 lintcode 31. Partition Array https://www.lintcode.com/problem/partition-array/description 首先外层的循环是left <= right 考虑相等的情况可以保证结束循环的时候两种情况 1 right 和 left左右相邻 2 right 和 left 中间空了一个,左右排列。如果条件是left < right 那么当left == right 时跳出循环,nums[left]还要再判断一次。 partition array 的同向双指针做法和quick sort是非常像的,但是在具体的细节上两者的模板有一定的不同。 public int partitionArray(int[] nums, int k) { if(nums == null || nums.length == 0)return 0; int left = 0, right = nums.length - 1; while(left <= right){ while(left <= right && nums[left] < k){ left++; } while(left <= right &&

刷题No28. copy-list-with-random-pointer(深拷贝一个链表)(java)【链表】

不打扰是莪最后的温柔 提交于 2020-02-13 03:19:32
题目: 现在有一个这样的链表:链表的每一个节点都附加了一个随机指针,随机指针可能指向链表中的任意一个节点或者指向空。 请对这个链表进行深拷贝。 思路: 先将原节点进行复制 再将原节点的random指针进行复制 从链表中将复制的节点拆分出来 代码: package com.company; public class TestNo28 { static class RandomListNode{ int val; RandomListNode next,random; RandomListNode(int x){ this.val = x; } public String toString(){ if(this.next == null){ return String.valueOf(this.val); } return this.val + "->" + this.next.toString(); } } public static void main(String[] args) { TestNo28 t = new TestNo28(); RandomListNode head = new RandomListNode(0); head.next = new RandomListNode(2); head.next.next = new RandomListNode(5);

指向指针数组的指针与存储字符串的指针数组

北慕城南 提交于 2020-02-13 00:50:36
今天看到一道题目,突然把自己对指针的理解整混乱了。 题目是这样的:假设定义了一个指针数组tBooks如下, 请定义一个指向它的数组指针p ,让程序可以顺利执行,并按要求打印出数据。 代码: char *tBooks[] = { "《数据结构》", "《计算机组成原理》", "《C语言程序设计》", "《计算机网络》", "《哆啦A梦》" }; __A__ = __B__; printf("请打印出《哆啦A梦》:\n%s\n",__C__); 如果是直接定义一个每个指针元素指向指针的指针数组 ,那么题目就简单了。 只需要定义一个长度为4的元素指向指针的指针数组并将tBooks的二级指针的地址(就是指向字符串指针的指针的地址)赋予给新定义的指针即可 ,再对数组内地址进行字符串打印。 倘若利用指向指针的指针数组 代码: char **p[4] = &tBooks[0]; printf("请打印出《哆啦A梦》:\n%s\n",*p[3]); (因为指针数组tBooks存放的地址指向的是字符串指针,所以指针数组里的指针元素为二级指针&tBooks[0],整个数组的指针为三级指针&tBooks) 可题目要求使用数组指针完成,没办法,一时突然凝滞,于是经过长时间的推敲,最后勉强得到了原理: 可能有错误,等以后真正明白了回头看可能会改正 。 为了使用数组指针 来达到 指向指针的数组指针 的效果

必会,详细剖析11道嵌入式Linux C语言面试题

丶灬走出姿态 提交于 2020-02-13 00:43:15
预处理器(Preprocessor) 1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) 答: #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在这想看到几件事情: 1) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) 2) 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。 3) 意识到这个表达式将使一个16位机的整型数溢出, 因此要用到长整型符号L, 告诉编译器这个常数是长整型数。 4) 如果你在表达式中用到UL(表示无符号长整型),那么可能这就给面试者留下了很好的第一印象。记住第一印象很重要。 2 . 写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。 答: #define MIN(A,B) ((A) <= (B) ? (A) : (B)) 这个测试是为下面的目的而设的: 1) 标识#define在宏中应用的基本知识。这是很重要的。因为在 嵌入(inline)操作符 变为标准C的一部分之前,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。 2) 懂得在宏中小心地把参数用括号括起来 3) 我也用这个问题开始讨论宏的副作用,例如

字典树(Trie)

时光怂恿深爱的人放手 提交于 2020-02-12 22:56:28
一、基本概念:   字典树(Trie)是一种用于实现字符串快速检索的多叉树结构。字典树的每一个结点都拥有若干个字符指针,若在插入或检索字符串时扫描到一个字符 c,就沿着当前结点的 c 字符指针,走向该指针指向的结点。 1、初始化   一棵空字典树仅包含一个根节点,该点的字符指针均指向空。 2、插入操作   当需要插入一个字符串 str 时,我们另一个指针 p 指向根节点。人后,依次扫描 s 中的每一个字符 c :   (1)若 p 的 c 字符指针指向一个已经存在的结点 q,则令 p = q   若 p 的 c 字符指针指向空,则新建一个结点 q,令 p = q   当 s 中的字符扫描完毕时,在当前结点 p 上标记它是一个字符串的尾部 int trie [ maxn ] [ 26 ] , tot = 1 ; bool nd [ maxn ] ; void _insert ( char str [ ] ) { int p = 1 ; for ( int k = 0 ; str [ k ] ; k ++ ) { int ch = str [ k ] - 'a' ; if ( trie [ p ] [ ch ] == 0 ) trie [ p ] [ ch ] = ++ tot ; p = trie [ p ] [ ch ] ; } nd [ p ] = true ; } 2、检索操作

设计与声明

风流意气都作罢 提交于 2020-02-12 22:02:22
  所谓软件设计,是“令软件做出你希望它做的事情”的步骤和做法,通常以颇为一般性的构想开始,最终变成十足的细节,以允许特殊接口的开发。 条款18:让接口容易被正确使用,不易被误用   许多客户端错误可以因为导入新类型而获得预防。在防范“不值得拥有的代码”上,类型系统是你的主要同盟国。 class Date { public: Date(int month,int day,int year); }; Date(30,2,1997)//应该是2,30 //导入新类型防止接口被误用 struct Day { explicit Day(int d):val(d) {} //explicit 避免隐式的转换。 int val; }; struct Month { explicit Month(int d):val(d) {} //explicit 避免隐式的转换。 int val; }; struct Year { explicit Year(int d):val(d) {} //explicit 避免隐式的转换。 int val; }; class Date { public: Date(const Month& m,const Day& d,const Year& y); }; Date(Month(3),Day(30),Year(1997)); //可以用enum来表示月份