2
原文是在我自己博客中,小伙伴也可以点阅读原文进行跳转查看,还有好听的背景音乐噢背景音乐已取消~ 2333333

线性表

什么是线性表?就是一种连续或间断存储的数组,这里的连续和间断是针对物理内存空间中线性表元素之间是否连续,其中连续数组对应内置数组的实现方式,间断数组对应的是指针的实现方式,这种方式也称为链表实现。

也就是说,线性表有两种实现方式,一种是内置数组实现,另一种是链表实现。
下面来看一下,有哪些数据结构属于线性表吧!

栈(stack)

特性

  • 先进后出
  • 只有唯一的一个出入口

介绍

栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

通过上面的话语表达,相信不难理解栈的概念。下面我们上图感受一下栈和入栈出栈情况:

栈

上图中我们可以看到入栈、出栈的实际情况。只有一个入口(缺口),在这个缺口处,进行入栈和出栈操作。在现实生活中更形象的比喻就是垒砖。
砖一次一次往上叠加,取的时候也是从最上部取,一直取到底部的最后一块。

php实现

php也可以实现简单的栈,由于php中没有提供很好的操作指针的方式,所以只能通过数组的方式实现。使用连个函数就可以,它们分别是 array_pusharray_pop

  1. array_push 将一个或多个单元压入数组的末尾(入栈);
  2. 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图:

入栈.gif

从命令行的执行结果来看,我们先依次入栈1、2、3三个值,后来取出的时候,也是按照栈的先进后出,后进先出的特性出栈的。

队列(queue)

特性

  • 先进先出
  • 两个缺口,一入口,一个出口

介绍

队列(queue)是一种采用先进先出(FIFO)策略的抽象数据结构,它的想法来自于生活中排队的策略。在生活中比较形象的比喻就是排队了。

队列

php实现

同样的,php中也可以以数组的形式实现队列,两个函数array_pusharray_shift

  • 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);

图示:

队列.gif

从命令行的执行结果我们可以看到,我们依次入队 1、2、3三个值,出队的时候先出1,再出2.符合我们队列的特性,先进先出,后进后出。

单链表

特性

  • 由每一个节点组成
  • 每个节点中包含下一个节点的指针(*next)

介绍

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据

链表有两个比较重要的部分组成:

  1. 指针 指向下一个节点的地址,(即内存位置的直接地址)
  2. 节点 链表中的组成部分,对于单链表,一个节点里面包含节点数据和下一个节点的指针

单向链表

图中我们可以看到,单向链表由一个头指针、头节点、n个元素节点和尾节点组成。
其中头指针代表,我们根据这个指针可以找到对应的链表
头节点,用来存储链表的一些信息,比如链表长度,头节点指针指向第一个元素节点
每个节点中又包括,节点数据(data)和指针(*next指向下一个元素节点)、
一直到尾节点为null

双向链表

特性

  1. 同单链表类似由一个一个的节点组成
  2. 与单向链表不同的是,每个节点中包含了除数据(data)之外的上一个节点的指针(*prev)和下一个节点的指针(*next)

介绍

双向链表又叫做双链表;跟单向链表不同的是,他的每个节点都有两个指针,一个指向前面的一个节点,一个指向后面的节点。通过这两个指针我们可以很方便的通过某一个节点,访问到相(前)邻(后)的两个节点。

我们来看一下,双向链表的图示:

双向链表

图中我们可以看到,除了头节点和尾节点之外,每个中间节点与节点之间都是首尾相连,每个节点保存了上一个节点的指针和下一个节点的指针,这就是与单链表的不同之处。

注:我们也可以构造双向循环链表;尾节点的下一个指针*next指向头节点,而头节点的*prev指向尾节点;这样就构成了一个双向循环链表;下图所示,我们只需把双向链表简单改造一下即可:

双向循环链表

总结

以上,就是本篇文章介绍的内容了。
数据结构很多,也很高深,其中的算法知识,也让人回味无穷。


命中水ヽ
5k 声望269 粉丝