指针数组

go map数据结构和源码详解

别说谁变了你拦得住时间么 提交于 2019-12-03 07:58:52
目录 1. 前言 2. go map的数据结构 2.1 核心结体体 2.2 数据结构图 3. go map的常用操作 3.1 创建 3.2 插入或更新 3.3 删除 3.4 查找 3.5 range迭代 3.5.1 初始化迭代器mapiterinit() 3.5.2 迭代过程mapiternext() 4. go map的扩容缩容 4.1 扩容缩容的基本原理 4.2 为什么叫“伪缩容”?如何实现“真缩容”? 5 Q&A关键知识点 5.1 基本原理 5.2 时间复杂度和空间复杂度分析 1. 前言 本文以go1.12.5版本分析,map相关的源码在runtime包的map开头的几个文件中,主要为map.go。 go的map底层实现方式是hash表(C++的map是红黑树实现,而C++ 11新增的unordered_map则与go的map类似,都是hash实现)。go map的数据被置入一个由桶组成的有序数组中,每个桶最多可以存放8个key/value对。key的hash值(32位)的低阶位用于在该数组中定位到桶,而高8位则用于在桶中区分key/value对。 go map的hash表中的基本单位是桶,每个桶最多存8个键值对,超了,则会链接到额外的溢出桶。所以go map是基本数据结构是hash数组+桶内的key-value数组+溢出的桶链表 当hash表超过阈值需要扩容增长时

指针数组的初始化

非 Y 不嫁゛ 提交于 2019-12-03 07:42:28
指针数组的初始化:   指针数组的初始化语法与其他类型对象的初始化语法类似,下面是一个例子: char *month_name(int n) {   static char *name[] = {     "Illegal month","January","February","March","April","May","June","july",     "August","September","October","November","December"     };   return (n < 1 || n > 12) ? name[0] : name[n]; } 其中name是一个一维数组,数组的元素为字符指针。name数组的初始化通过一个字符串列表实现, 列表中的每个字符串赋值给数组相应位置的元素。第i个字符串的所有字符存储在存储器的某个位置, 指向它的指针存储在name[i]中。由于上述声明没有指明name的长度,因此编译器会对初值个数进行 统计,并将这一准确数字填入数组的长度。 来源: https://www.cnblogs.com/TheFly/p/11783610.html

快速排序,归并排序,堆排序的数组和单链表实现

和自甴很熟 提交于 2019-12-03 07:11:42
原文链接: https://www.cnblogs.com/DarrenChan/p/8807112.html 这三个排序的时间复杂度都是O(nlogn),所以这里放到一起说。 回到顶部 1. 快速排序 # 快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 步骤为: 从数列中挑出一个元素,称为"基准"(pivot), 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。 最优时间复杂度:O(nlogn) 最坏时间复杂度:O(n2) 稳定性:不稳定 从一开始快速排序平均需要花费O(n log n)时间的描述并不明显

第七周

為{幸葍}努か 提交于 2019-12-03 06:55:59
学号 2019-2020-20182321 《数据结构与面向对象程序设计》第七周学习总结 教材学习内容总结 栈是一个线性集合,其内部元素遵循先进后出的规律,即先进来的最后才能出去。(因其删除和添加元素都是在栈的一段进行) 栈的操作都在栈顶进行,如果把栈看成是一长串数组,那么栈顶就类似于数组的末尾,栈通常有着五种基本操作 pop 删除栈顶元素 push 将元素添加到栈顶 peek 查看栈顶元素 isEmpty 栈是否为空 size 判定栈中元素的个数 java可以用泛型来定义类,即可以定义一个类,它保存操作管理直到实例化时才会需要决定类型的对象。如Competition 是一个类型为T的类,当实例化对象的时候,它可以实例化为整数型,也可以实例化为浮点型等等。 实现栈的方法可以是利用数组或者是利用链表,但在实现的时候也必须要顾忌几个方面的异常 入栈时如果栈满 出栈时如果栈空 扫描完表达式时栈中的值如果多余一个 栈满的原因应该是数据结构出的问题,即算法出了问题,严格意义上说,满栈是不存在的,这辈子都不可能满栈的,虽然听起来是不太可能,但是从栈的角度来说,栈是无限的,是一个无限集,只不过是数据结构有限罢了 链表相对于数组的缺点是,链表在指定性上不如数组,如果想要直接访问某个在栈中的元素,用数组时我们就可以直接跳到那里,但是用链表的话就必须要一级一级的往下走,且必须设置头指针

最基础的数据结构-左轻侯

一曲冷凌霜 提交于 2019-12-03 06:07:53
作者:左轻侯 创建时间:2007-03-04 22:29:06 最后修改时间:2008-01-18 22:07:52 本文发表于《程序员》2007年第3期      最基础的数据结构   左轻侯   2007.2.3      引言       任何一个受过专业训练的程序员,对“数据结构”这门课程中涉及到的各种数据结构都不会感到陌生。但是,在实际的编程工作中,大部分的数据结构都不会用到,而且也许永远都不会用到。造成这种现象的原因有二:一是根据80/20法则,常用的数据结构只会占到少部分;二是计算机语言往往已经对常用的数据结构进行了良好的封装,程序员不需要关心内部的实现。    虽然如此,深入地理解基本数据结构的概念和实现细节,仍然是每一个程序员的任务。这不仅是因为,掌握这些知识,将有利于更加正确和灵活地应用它们,而且也是因为,对于语言背后的实现细节的求知欲,是一个优秀的程序员的素质。    本文将讨论实际编程最经常使用的三种数据结构:字符串、数组和Hash表,比较它们在不同语言中的实现思路,并涉及它们的使用技巧。      字符串    严格地说,字符串(string)甚至不能算作一种单独的数据结构,至少在C语言中,它仅仅是某种特定类型的数组而已。但是,字符串在实际使用中是如此重要,在不同语言中的实现又差异颇大,因此,它值得被作为一种抽象数据类型单独进行讨论

C语言qsort函数总结

一个人想着一个人 提交于 2019-12-03 05:25:08
   前几天在leetcode上刷题,用qsort对二维数组进行排序,发现不会写qsort的比较函数。后面在网上找了几篇博客才弄明白,趁今天有空,对这个做一下总结,主要是以下4个方面: 1、qsort总体介绍 2、qsort应用于一维数组 3、qsort应用于指针数组 4、qsort应用于二维数组 1、qsort总体介绍   函数声明:void qsort(void *base, size_t nitems, size_t size, int (*compare)(const void *, const void*))   参数解释:     base-- 指向要排序的 数组 的第一个元素的指针。注意这里说是数组,所以必须是对连续的内存块进行排序。     nitems-- 由 base 指向的数组中元素的个数     size-- 数组中每个元素的大小,以字节为单位     compare-- 用来比较两个元素的函数。这是qsort最难的一部分了。这里主要要注意以下2点:1、在写compare函数时,你的两个形参必须是const void *型,但是在compare函数内部你又必须将const void *类型的形参转换为实际的类型。这是我最当时最难以理解的一个问题了:我需要转换成什么类型。看了别人的总结才知道,是: 指向数组元素的指针,指向数组元素的指针,指向数组元素的指针

strlen()与sizeof()

大城市里の小女人 提交于 2019-12-03 02:29:55
一、strlen() strlen()为计算字符串长度的函数,以‘\0’为字符串结束标志。注意:其传入参数必须是字符串指针(char*), 当传入的是数组名时,实际上数组退化成指针了。 二、sizeof() sizeof()为运算符,用于计算所分配给元素的内存大小,其返回结果类型为size_t。 来源: https://www.cnblogs.com/socks/p/11714347.html

golang string转换数组

匿名 (未验证) 提交于 2019-12-03 00:43:02
如果去掉 arr *[5]rune 中的5, 则指参数变成了切片类型, 数组的指针就传不进去了, 编译会报错, 那么难道一定要写死数组的长度吗? 这样也太不优雅. 代码例子如下: func StringToRuneArr(s string , arr []rune) { src : = []rune(s) for i, v := range src { if i >= len(arr) { break } arr[i] = v } } func main(){ str : = " 这是一个字符串ABCDEF " var arr [ 10 ]rune utility.StringToRuneArr(str, arr[:]) fmt.Println( string (arr[:])) } 原文:https://www.cnblogs.com/elonlee/p/9363461.html

我也不知道标题应该定为什么

匿名 (未验证) 提交于 2019-12-03 00:39:02
之前的排序都是基于比较的排序,而桶排序是基于数据状况的排序,这就比较麻烦了,虽然很快,可是分析数据状况是很繁琐的。桶排序 是可以实现稳定排序的。常用有两种实现,一种是计数排序,一种是基数排序 (最后一节)。 桶排序的扩展,排序后的最大相邻数差值问题。有N个数字,建立N+1个桶,最大的差值不可能来自一个桶中,只能来自相邻的桶中,这样就可以得到最大差值了。 用数组结构实现大小固定的队列和栈? 数组实现栈,通过一个指针变量指向下一个进入栈中的元素的位置就可以实现了。 用数组实现队列,有3个变量,一个是start,一个是end,一个是size,start和end没有关系,仅仅和size有关系,如果size大小等于0,就表示没有东西了,直接报错。如果size大小大于数组长度,说明已经满了,也就直接报错返回,都则就可以循环的使用start和end 。 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返 回栈中最小元素的操作。 【要求】 1.pop、push、getMin操作的时间复杂度都是O(1)。没说空间限制 2.设计的栈类型可以使用现成的栈结构。 设计两个栈,同时压入就可以了。弹出的时候同步弹出。如果栈顶元素比min的栈顶元素小,压入该元素,否则压入min栈的栈顶元素。 还有一种是,如果栈为空,min栈直接压入,否则,如果当前值小于等于min栈顶元素,就压入,否则不压入

数据结构――一些概念

匿名 (未验证) 提交于 2019-12-03 00:39:02
数据结构就是研究数据的 逻辑结构 和 物理结构 以及它们之间 相互关系 ,并对这种结构定义相应的运算,而且确保经过这些运算后所得到的新结构仍然是原来的结构类型。 数据:所有能被输入到计算机中,且能被计算机处理的符号的集合。是计算机操作的对象的总称。 数据元素:数据(集合)中的一个“个体”,数据及结构中讨论的 基本 单位 数据项:数据的不可分割的最小单位。一个数据元素可由若干个数据项组成。 数据类型:在一种程序设计语言中,变量所具有的数据种类。整型、浮点型、字符型等等 逻辑结构:数据之间的相互关系。 集合 结构中的数据元素除了同属于一种类型外,别无其它关系。 线性结构 数据元素之间一对一的关系 树形结构 数据元素之间一对多的关系 图状结构或网状结构 结构中的数据元素之间存在多对多的关系 物理结构/存储结构:数据在计算机中的表示。物理结构是描述数据具体在内存中的存储(如:顺序结构、链式结构、索引结构、哈希结构)等 在数据结构中,从逻辑上可以将其分为线性结构和非线性结构 数据结构的基本操作的设置的最重要的准则是, 实现应用程序与存储结构的独立 。实现应用程序是“逻辑结构”,存储的是“物理结构”。逻辑结构主要是对该结构操作的设定,物理结构是描述数据具体在内存中的存储(如:顺序结构、链式结构、索引结构、希哈结构)等。 顺序存储结构中,线性表的逻辑顺序和物理顺序总是一致的。但在链式存储结构中