数据结构 --- 线性表学习(php模拟)
线性表:零个或多个数据元素的有限序列(注:以下都是用的整型数据模拟)
一 顺序存储结构(用一段地址连续的存储单元一次存储线性表的数据元素)
1.1 三个属性:存储空间的起始位置;最大存储容量;当前长度
注:数组长度是存放线性表的存储空间的长度(一般是不变的),不过语言可以动态增加容量,会带来性能损耗;
线性表长度是数据元素的个数;
线性表是从1开始数的,对应数组0的位置
1.2 获取元素、插入元素、删除元素(代码中展示)
1.3 顺序结构优缺点:
优点:无须为表示表中元素之间的逻辑关系而增加额外的存储空间;可以快速地存取表中任一位置元素
缺点:插入和删除操作需要移动大量的元素;当线性表长度裱花较大时,难以确定存储空间容量;造成存储空间'碎片'
//用一维数组模拟线性表
class Sequential_Structure
{
//线性表的长度
private $num = 0;
//数组长度
private $len = 0;
//数组模拟
private $arr = array(); /**
* 初始化结构
* @param Int $len 最大数组长度
* @param Array $arr 数组
* @return
*/
public function __construct($len, Array $arr)
{
$this->len = $len;
$length = count($arr);
if($length > 0 && $length <= $len)
{
$this->arr = $arr;
$this->num = $length;
}
} /**
* 获取线性表元素
* @param Int $i 需要获取的第几个元素
* @return
*/
public function get_elem($i)
{
if($this->num == 0 || $i < 1 || $i > $this->num) //判断查找是否合理
return false;
return $this->arr[$i-1]; //返回数据,时间复杂度O(1)
} /**
* 插入元素(顺序结构中,插入元素后,后面所有的数据都要后移,平均时间复杂度O(1)):
* 如果插入位置不合理,失败
* 如果线性长度大于数组长度,则返回错误或者动态增加容量
* 从最后一个元素开始向前遍历到第i个位置,分别将它们向后移动一个位置
* 将元素插入i位置
* @param Int $i 需要插入到第几个元素
* @param Int $elem 插入的节点
* @return bool
*/
public function insert_elem($i, $elem)
{
if($this->num == $this->len) //顺序线性表已满
return false;
if($i < 1 || $i > ($this->num+1)) //i不在范围之内
return false;
if ($i <= $this->num) //若数据插入位置不在表尾
{
for($k = $this->num-1; $k >= $i-1; --$k) //后面所有元素往后移动一位
$this->arr[$k+1] = $this->arr[$k];
}
$this->arr[$i-1] = $elem; //插入元素
++$this->num;
return true;
} /**
* 删除元素(顺序结构中,插入元素后,后面所有的数据都要前移,平均时间复杂度O(1)):
* 如果删除位置不合理,失败
* 将元素删除
* 从最后删除元素开始向后遍历到最后,分别将它们向前移动一个位置
* @param Int $i 需要仓储的第几个元素
* @return bool
*/
public function delete_elem($i)
{
if($this->num == 0) //线性表为空
return false;
if($i < 1 || $i > $this->num) //删除位置不正确
return false;
if($i < $this->num) //删除位置不是表尾
{
for($k = $i; $k < $this->num; ++$k) //前移
$this->arr[$k-1] = $this->arr[$k];
}
unset($this->arr[$this->num-1]);
--$this->num;
return true;
} /**
* 获取顺序表
* @return
*/
public function get_arr()
{
return $this->arr;
} /**
* 获取长度
* @return
*/
public function get_len()
{
return array('num' => $this->num , 'len' => $this->len);
}
} $link = new Sequential_Structure(10,[1,4,8,7]);
echo $link->get_elem(2);
var_dump($link->insert_elem(5,5));
var_dump($link->get_arr());
var_dump($link->get_len());
var_dump($link->delete_elem(1));
var_dump($link->get_arr());
var_dump($link->get_len());
输出:
boolean true
array (size=5)
0 => int 1
1 => int 4
2 => int 8
3 => int 7
4 => int 5
array (size=2)
'num' => int 5
'len' => int 10
boolean true
array (size=4)
0 => int 4
1 => int 8
2 => int 7
3 => int 5
array (size=2)
'num' => int 4
'len' => int 10
二 链表存储结构(n个节点链结成一个链表)
2.1 单链表(用数组模拟)
2.1.1 链表中第一个结点的存储位置为头指针(通常为了方便对链表进行操作,会在单链表的第一个结点前附设一个头结点)
注 头指针:指向链表第一个结点的指针,若链表有头结点,这是指向头结点的指针;无论链表是否为空,头指针不为空
头结点:放在第一元素的结点之前
/**
* 用一维数组模拟线性表
* array('data'=>data,'cur'=>cur) data为存放数据,cur为下个数组元素下标
*/
class Simple_Link
{
//数组长度
private $len = 0;
//数组模拟
private $arr = array();
//数组中空闲的下标
private $space_arr = array(); /**
* 初始化结构
* @param Int $len 最大数组长度
* @param Array $arr 数组
* @return
*/
public function __construct($len, Array $arr)
{
$this->len = $len;
$length = count($arr);
$this->arr[0]['data'] = $length;
$this->arr[0]['cur'] = 0;
for($i = 0; $i < $length; ++$i)
$this->arr[$i]['cur'] = $i+1; //模拟链表的指向 if($length)
$this->arr[$length]['cur'] = 0; //最后一个结点指针空 for($i = $length + 1; $i <= $len-$length ; ++$i) //空闲数组
array_unshift($this->space_arr,$i);
} /**
* 获取线性表元素:
* 初始化$j从1开始
* 当$j<$i,遍历链表
* @param Int $i 需要获取的第几个元素
* @return
*/
public function get_elem($i)
{
if($i < 1 || $i > $this->arr[0]['data'])
return false;
$j = 1;
$cur = $this->arr[0]['cur']; //指向第一个结点
while($j < $i)
{
$cur = $this->arr[$cur]['cur'];
++$j;
}
return $this->arr[$cur]['data'];
} /**
* 插入元素:
* 初始化$j从1开始
* 当$j<$i,遍历链表
* 将元素插入i位置
* @param Int $i 需要插入到第几个元素
* @param Int $elem 插入的节点
* @return bool
*/
public function insert_elem($i, $elem)
{
$len = $this->arr[0]['data'] + 1;
if($i < 1 || $i > $len)
return false;
$j = $this->malloc(); //获取空闲下标
if(!$j)
return false;
$this->arr[$j]['data'] = $elem; $k = 1;
$index = 0;
$cur = !empty($this->arr[0]['cur']) ? $this->arr[0]['cur'] : 0; //指向第一个结点
while($k < $i)
{
//记录当前cur和下一个cur
$index = $cur;
$cur = $this->arr[$index]['cur'];
++$k;
}
//改变指针指向
$this->arr[$index]['cur'] = $j;
$this->arr[$j]['cur'] = $cur; ++$this->arr[0]['data'];
return true; } /**
* 删除元素:
* 初始化$j从1开始
* 当$j<$i,遍历链表
* 将i位置删除
* @param Int $i 需要删除第几个元素
* @return bool
*/
public function delete_elem($i)
{
$len = $this->arr[0]['data'];
if($i < 1 || $i > $len)
return false; $k = 1;
$index = 0;
$cur = !empty($this->arr[0]['cur']) ? $this->arr[0]['cur'] : 0; //指向第一个结点
while($k < $i)
{
//记录当前cur和下一个cur
$index = $cur;
$cur = $this->arr[$index]['cur'];
++$k;
}
//改变指针指向
$this->arr[$index]['cur'] = $this->arr[$cur]['cur']; $this->free($cur);
unset($this->arr[$cur]);
--$this->arr[0]['data'];
return true;
} /**
* 获取空闲的结点下标,也就是相当于申请一个空结点
* @return
*/
private function malloc()
{
if(empty($this->space_arr))
return false;
return array_pop($this->space_arr);
} /**
* 释放结点
* @param Int $cur 需要回收的结点下标
*/
private function free($cur)
{
array_push($this->space_arr, $cur);
} /**
* 打印
* @return
*/
public function print_arr()
{
$i = 0;
if(!empty($this->arr[0]['data']))
{ while($this->arr[$i]['cur'])
{
$i = $this->arr[$i]['cur'];
echo $this->arr[$i]['data'].' ';
}
}
} /**
* 获取长度
* @return
*/
public function get_len()
{
return array('num' => $this->arr[0]['data'] , 'len' => $this->len);
}
} $link = new Simple_Link(10,array());
var_dump($link->insert_elem(1,5));
var_dump($link->insert_elem(2,4));
var_dump($link->insert_elem(1,6));
var_dump($link->delete_elem(3));
echo $link->print_arr();
var_dump($link->get_len()); 输出:
boolean true
boolean true
boolean true
boolean true
6 5
array (size=2)
'num' => int 2
'len' => int 10
数据结构 --- 线性表学习(php模拟)的更多相关文章
- [数据结构-线性表1.2] 链表与 LinkedList<T>(.NET 源码学习)
[数据结构-线性表1.2] 链表与 LinkedList<T> [注:本篇文章源码内容较少,分析度较浅,请酌情选择阅读] 关键词:链表(数据结构) C#中的链表(源码) 可空类 ...
- [从今天开始修炼数据结构]线性表及其实现以及实现有Itertor的ArrayList和LinkedList
一.线性表 1,什么是线性表 线性表就是零个或多个数据元素的有限序列.线性表中的每个元素只能有零个或一个前驱元素,零个或一个后继元素.在较复杂的线性表中,一个数据元素可以由若干个数据项组成.比如牵手排 ...
- 数据结构-线性表的链式存储相关算法(C语言实现)
链表的简单介绍 为什么需要线性链表 当然是为了克服顺序表的缺点,在顺序表中,做插入和删除操作时,需要大量的移动元素,导致效率下降. 线性链表的分类 按照链接方式: 按照实现角度: 线性链表的创建和简单 ...
- 数据结构线性表(js实现)
最近在复习数据结构的过程中,发现基本上数据结构都是用C来实现的,自己之前学习的时候也是用C去写的,由于目前对js更为熟悉一些,所以这里选择使用js去实现其中的某些算法和结构.实际上算法和语言关系不大, ...
- C# 数据结构 线性表(顺序表 链表 IList 数组)
线性表 线性表是最简单.最基本.最常用的数据结构.数据元素 1 对 1的关系,这种关系是位置关系. 特点 (1)第一个元素和最后一个元素前后是没有数据元素,线性表中剩下的元素是近邻的,前后都有元素. ...
- [置顶] ※数据结构※→☆线性表结构(queue)☆============循环队列 顺序存储结构(queue circular sequence)(十)
循环队列 为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量.存储在其中的队列称为循环队列(Circular Queue). ...
- [置顶] ※数据结构※→☆线性表结构(queue)☆============优先队列 链式存储结构(queue priority list)(十二)
优先队列(priority queue) 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除.在优先队列中,元素被赋予优先级.当访问元素时,具有最高优先级的元素最先删除.优先队列具有 ...
- [置顶] ※数据结构※→☆线性表结构(stack)☆============栈 序列表结构(stack sequence)(六)
栈(stack)在计算机科学中是限定仅在表尾进行插入或删除操作的线性表.栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据.栈 ...
- 数据结构----线性表顺序和链式结构的使用(c)
PS:在学习数据结构之前,我相信很多博友也都学习过一些语言,比如说java,c语言,c++,web等,我们之前用的一些方法大都是封装好的,就java而言,里面使用了大量的封装好的方法,一些算法也大都写 ...
随机推荐
- 图论(网络流):[SCOI2015]小凸玩矩阵
Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最 ...
- Fragmen横竖屏切换,导致页面混乱,oncreateView重复调用
在清单文件Activity设置属性 android:screenOrientation="landscape" android:configChanges="screen ...
- 外星人的供给站 (区间覆盖 t贪心)
/** 区间覆盖问题 分析: 每个点可以确定两个圆心 圆心的范围形成 一个区间 在这个区间上以任意一点画圆便可将此点 包含在内 如果有两个点所确定的区间相交了 说明这两个点可以用一个圆包含在内 即用一 ...
- Codeforces Round #326 (Div. 1) - C. Duff in the Army 树上倍增算法
题意:一个n个点的数, m个人住在其中的某些点上, 每个人的标号1-m, 询问u-v 路径上标号前a个人,并输出标号,a < 10. 作法, 利用倍增, ID[j][i] 表示i到i的第2^j个 ...
- [转]windows10 64位环境下安装mysql5.7.17
今天以zip模式在windows10 64位环境下安装mysql5.7,到最后一步提示mysql服务无法启动. 安装步骤如下: 1.配置环境变量 我的电脑->属性->高级->环境变量 ...
- 移动端转PC --> PC跳转移动端
<script type=”text/javascript”>try {var urlhash = window.location.hash;if (!urlhash.match(“fro ...
- JVM调优之jstack找出发生死锁的线程
1.执行死锁程序 2.执行 jstack -l 21733 | more 结果如下: 死锁程序: public static void main(String[] args) { // TODO Au ...
- 雅虎NCP:网络黄页的终结者
雅虎NCP是什么,NCP能做什么,为什么NCP能够成为网络黄页的终结者.NCP在颠覆既有市场格局的同时,其真实目的时什么?是成为网络化操作系统还是图谋最大化长尾广告.笔者相信,过不了多久,市场将会告诉 ...
- 使用Dreamwaver cc中的SVN功能,用于传输BAE和SAE中的文件
前沿: 假期使用BAE和SAE开发应用,两个服务器都需要通过SVN提交代码,因为平时大多使用Dreamwaver,所以查了查资料,通过Subversion方便了开发. 因为网上的资料都不全,所以根据自 ...
- iOS平台基于ffmpeg的视频直播技术揭秘
现在非常流行直播,相信很多人都跟我一样十分好奇这个技术是如何实现的,正好最近在做一个ffmpeg的项目,发现这个工具很容易就可以做直播,下面来给大家分享下技术要点: 首先你得编译出ffmpeg运行所需 ...