数据结构与算法系列之数组

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"什么是数组?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"忘了在哪本书看见过一句话“理解了概念性的东西,你就学会了70%”"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"回到主题,什么是数组?"},{"type":"text","marks":[{"type":"strong"}],"text":"数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"概念中有两个关键的地方:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"数组是一种线性数据结构"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"数组中存储的是连续的内存空间和相同类型的数据"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"什么是线性数据结构"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有数据结构基础的小伙伴都应该知道,线性结构就是数据排成一条线一样的数据结构,也就意味着它仅有前后两个方向,比如队列、单链表、栈等,也是线性结构"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/07/078feb8f3368e05ab7f5b5690d069a7a.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"与它相对的就是非线性表,最典型的就是树和图。他们的特点就是并不是只有前后这种关系"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f7/f7bd14a2f4eedf2a4705c0a05822813e.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"连续的内存空间和相同类型的数据"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"正因为有了这个特性,使得数组可以进行“随机访问”。虽然访问数组中某个元素变得很快,但缺点就是在修改(删除、插入)数组的时候,操作会变得很麻烦,因为要保证数组内存空间的连续性,所以不得不进行繁琐的数据移动"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"假设有一个长度为5的int类型的数组var a [5]int,假设给这个数组分配的内存空间首地址是1000,则这个数组分配的内存空间为1000~1019,看下图"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/67/670471f18c82fa58a7df34290933ab0a.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"操作系统会为每一个内存单眼分配一个地址,通过这个地址来访问内存中的数据。当操作系统需要随机访问数组中的某一个元素时,它会通过下边这个寻址公式来计算出某个元素的存储地址"}]},{"type":"codeblock","attrs":{"lang":"php"},"content":[{"type":"text","text":"a[i]_address = base_address + i * data_type_size\n\ndata_type_size:表示数组中每个元素的大小。比如int类型,它占用的是4个字节,所以这里data_type_size就是4"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"数组和链表的区别是什么"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过上边对数组的介绍,可以看出来,数组适合查找操作。但是查找的时间复杂度并不为O(1)。即便是排好序的数组,你用二分查找,时间复杂度也是O(logn)。所以,数组支持随机访问,根据下标随机访问的时间复杂度为O(1)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"数组相关操作"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"插入元素"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"数组头部插入元素"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在数组的头部插入元素,为了保证空间的连续性,需要将数组中所有的元素向后移一位,然后将待插入元素放入到首部位置"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/9e/9e32948a0cedc8f821b67a130f5cedec.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"代码实现"}]},{"type":"codeblock","attrs":{"lang":"php"},"content":[{"type":"text","text":"function insertIntoHead($elem, $arr)\n {\n echo \"原始数组:\".PHP_EOL;\n print_r($arr);\n\n $i = 0;\n $len = count($arr);\n while ($i < $len) {\n $arr[$len-$i] = $arr[$len-$i-1];\n $i++;\n }\n\n $arr[0] = $elem;\n\n echo \"头部插入元素之后结果:\".PHP_EOL;\n print_r($arr);\n }"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"数组中间插入元素"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在数组的中间某个位置插入元素,需要将待插入位置以后的元素均向后移动一位"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b6/b615a04b0a15cac945b08a4a7ff9f31f.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"代码实现"}]},{"type":"codeblock","attrs":{"lang":"php"},"content":[{"type":"text","text":"function insertIntoMid($elem, $position, $arr)\n {\n echo \"原始数组:\".PHP_EOL;\n print_r($arr);\n $len = count($arr);\n\n $i = $position-1;\n $value = $arr[$i];\n $arr[$i] = $elem;\n $head = $i+1;\n $offset = $position-1;\n\n while ($i < $len) {\n $arr[$len-$i+$offset] = $arr[$len-$i-1+$offset];\n $i++;\n }\n $arr[$head] = $value;\n\n echo \"头部插入元素之后结果:\".PHP_EOL;\n print_r($arr);\n }"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"数组尾部插入元素"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在尾部插入元素,不需要移动元素,直接放在当前的末尾元素后边即可"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"删除元素"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"数组头部删除元素"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"删除数组头部元素,将所有的元素向前移动一位即可"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5d/5db4466d193df10a1586d28fd8dac6f2.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"代码实现:"}]},{"type":"codeblock","attrs":{"lang":"php"},"content":[{"type":"text","text":"function delHead($arr)\n{\n echo \"删除前:\".PHP_EOL;\n print_r($arr);\n\n for ($i=0; $i
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章