原文是在我本身博客中,小伙伴也能够点 阅读原文进行跳转查看,还有好听的背景音乐噢背景音乐已取消~ 2333333
什么是线性表?就是一种连续或间断存储的数组,这里的连续和间断是针对物理内存空间中线性表元素之间是否连续,其中连续数组对应内置数组的实现方式,间断数组对应的是指针的实现方式,这种方式也称为链表实现。php
也就是说,线性表有两种实现方式,一种是内置数组实现,另外一种是链表实现。
下面来看一下,有哪些数据结构属于线性表吧!html
栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是 仅容许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另外一端称为栈底。向一个栈插入新元素又称做进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称做出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
经过上面的话语表达,相信不难理解栈的概念。下面咱们上图感觉一下栈和入栈出栈状况:算法
上图中咱们能够看到入栈、出栈的实际状况。只有一个入口(缺口),在这个缺口处,进行入栈和出栈操做。在现实生活中更形象的比喻就是垒砖。
砖一次一次往上叠加,取的时候也是从最上部取,一直取到底部的最后一块。数组
php也能够实现简单的栈,因为php中没有提供很好的操做指针的方式,因此只能经过数组的方式实现。使用连个函数就能够,它们分别是 array_push和array_pop数据结构
array_push
将一个或多个单元压入数组的末尾(入栈);array_pop
弹出数组最后一个单元(出栈)简单代码示例:函数
$arr = []; array_push($arr, 1); // $arr[] = 1; print_r($arr); sleep(1); array_push($arr, 2); // $arr[] = 2; print_r($arr); sleep(1); array_push($arr, 3); // $arr[] = 3; print_r($arr); sleep(1); $val = array_pop($arr); echo $val . "\n\n"; print_r($arr); sleep(1); $val = array_pop($arr); echo $val . "\n\n"; print_r($arr);
把这段代码放在cli下跑,就能看到效果了,看一下运行gif图:spa
从命令行的执行结果来看,咱们先依次入栈一、二、3三个值,后来取出的时候,也是按照栈的先进后出,后进先出的特性出栈的。.net
队列(queue)是一种采用先进先出(FIFO)策略的抽象数据结构,它的想法来自于生活中排队的策略。在生活中比较形象的比喻就是排队了。
一样的,php中也能够以数组的形式实现队列,两个函数array_push和array_shift命令行
能够发现array_push和上面的栈入栈是同一个函数,其实两个函数的做用同样。用在这里就表示为入队了。指针
简单代码示例:
header("Content-type:text/html;charset=utf-8"); $arr = []; echo '入队-1 array_push($arr, 1)' . "\n"; array_push($arr, 1); // $arr[] = 1; print_r($arr); sleep(1); echo '入队-2 array_push($arr, 2)' . "\n"; array_push($arr, 2); // $arr[] = 2; print_r($arr); sleep(1); echo '入队-3 array_push($arr, 2)' . "\n"; array_push($arr, 3); // $arr[] = 3; print_r($arr); sleep(1); echo '出队-3 array_shift($arr)' . "\n"; $val = array_shift($arr); echo $val . "\n\n"; print_r($arr); sleep(1); echo '出队-2 array_shift($arr)' . "\n"; $val = array_shift($arr); echo $val . "\n\n"; print_r($arr);
图示:
从命令行的执行结果咱们能够看到,咱们依次入队 一、二、3三个值,出队的时候先出1,再出2.符合咱们队列的特性,先进先出,后进后出。
*next
)单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每一个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是链接每一个结点的地址数据
链表有两个比较重要的部分组成:
图中咱们能够看到,单向链表由一个头指针、头节点、n个元素节点和尾节点组成。
其中头指针表明,咱们根据这个指针能够找到对应的链表
头节点,用来存储链表的一些信息,好比链表长度,头节点指针指向第一个元素节点
每一个节点中又包括,节点数据(data)和指针(*next指向下一个元素节点)、
一直到尾节点为null
data
)以外的上一个节点的指针(*prev
)和下一个节点的指针(*next
)双向链表又叫作双链表;跟单向链表不一样的是,他的每一个节点都有两个指针,一个指向前面的一个节点,一个指向后面的节点。经过这两个指针咱们能够很方便的经过某一个节点,访问到相(前)邻(后)的两个节点。
咱们来看一下,双向链表的图示:
图中咱们能够看到,除了头节点和尾节点以外,每一个中间节点与节点之间都是首尾相连,每一个节点保存了上一个节点的指针和下一个节点的指针,这就是与单链表的不一样之处。
注:咱们也能够构造双向循环链表;尾节点的下一个指针*next
指向头节点,而头节点的*prev
指向尾节点;这样就构成了一个双向循环链表;下图所示,咱们只需把双向链表简单改造一下便可:
以上,就是本篇文章介绍的内容了。数据结构不少,也很高深,其中的算法知识,也让人耐人寻味。