2019年7月11日 星期四(数据结构和算法)

•对拥有C,C++,Java其它语言基础的人员,强烈建议观看c,c++,java版本的数据结构资料。

•数据结构的意义与重要性

•数据结构链表与队列

•数据结构双向链表与循环链表

•数据结构栈及其应用

•树与二叉树以及其应用

PHP数据结构和算法

1.数据结构的概念

数据结构就是研究数据的逻辑结构物理结构以及它们之间相互关系,并对这种结构定义相应的运算。

数据结构是计算机存储、组织数据的方式及运算规则。

数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.物理存储结构

1.顺序存储:把逻辑上相邻的元素存储在物理位置上也相邻的存储单元里,元素之间的关系由存储单元的邻接关系来体现。一般适用于线性的数组和链表,对于非线性的树和图则不适合。

2.链接存储:不要求逻辑上相邻的元素在物理位置上也相邻,借助指示元素存储地址的指针表示元素之间的逻辑关系。其优点是不会出现碎片现象,充分利用所有存储单元;缺点是每个元素因存储指针而占用额外的存储空间,并且只能实现顺序存取。

3.索引存储:在存储元素信息的同时,还建立附加的索引表。索引表中的每一项称为索引项,索引项的一般形式是:(关键字,地址)。其优点是检索速度快;缺点是增加了附加的索引表,会占用较多的存储空间。另外,在增加和删除数据时要修改索引表,因而会花费较多的时间。

4.散列存储:根据元素的关键字直接计算出该元素的存储地址,又称为Hash存储。其优点是检索、增加和删除结点的操作都很快;缺点是如果散列函数不好可能出现元素存储单元的冲突,而解决冲突会增加时间和空间开销。

3.时间复杂度

时间复杂度是一把直尺,用来度量程序执行的时间效率。

算法的时间复杂度通常有如下:

1.o(1)

2.o(logn)

3.o(n)

4.o(n^2)

5.o(n^k)

O(1) 常数阶 < O(logn) 对数阶 < O(n) 线性阶 < O(nlogn) < O(n^2) 平方阶 < O(n^3) < { O(2^n) < O(n!) < O(n^n) } 红色算法复杂度不推荐,如果程序是如此高的复杂度,直接考虑换算法。

4.循环转递归

任何时候循环可以实现的,都可以使用递归来实现。

function recursion($n,&$sum){
   for ($i=1; $i <=100 ; $i++){ 
       if($n==1){
           $sum++;
       }else{
           recursion($n-1,$sum);
       }
   }
}

轻松实现任意层循环。

5.时间复杂度

  1. a = a= a=a+ b ; b; b;b= a − a- ab; a = a= a=a-$b;

以上每条代码频率只有1,无论有多少条语句,时间复杂度都是o(1)

  1. $sum=0;

for( I = 0 ; I=0; I=0;I<n;$I++)

s u m + = sum+= sum+=I;

以上代码运行次数为2n+1,系数和+1都省略掉,时间复杂度为o(n)

  1. $i=1;

​ while ( i &lt; i&lt; i<n)

i = i= i=i*2;

时间复杂度为o(log2n)

  1. $sum=0;                
    

​ for( i = 0 ; i=0; i=0;i< n ; n; n;i++)

​ for( j = 0 ; j=0; j=0;j< n ; n; n;j++)

​ $sum++;

时间复杂度为 o(n^2)

6.空间复杂度

空间复杂度是对一个算法在运行过程中临时占用存储空间(内存)大小的度量。

一个算法的空间复杂度包括算法程序所占用的空间,同时还包含初始数据所占用的空间以及算法执行过程中所需要的额外辅助空间。

(1)固定部分。主要包括指令空间(即代码空间)、数据空间(常量、简单变量)等所占的空间。这部分属于静态空间。

(2)可变空间,这部分空间的主要包括动态分配的空间,以及递归栈所需的空间等。这部分的空间大小与算法有关。

7.时空转换

用时间换空间,或者用空间来提升时间效率。

a 和 a和 ab值互换程序。

a = 11 ; a=11; a=11;b=13;

算法1: a = a= a=a+$b;

b = b= b=a-$b;

a = a= a=a-$b;

echo a . ” ” . a.” ”. a..b;

算法2: $tmp = $b;

b = b= b=a;

a = a= a=tmp;

echo a . ” ” . a.” ”. a..b;

写程序的时候,如果内存不紧张的话,我们可以用空间来换时间。

8.数据结构三大特征

在这里插入图片描述

9.程序是什么?

程序 =?

程序=数据结构+算法

设计好数据结构,程序就等于成功了一半。

数据结构是程序设计的基石。

PHP 链表与队列

1.链表的定义

•链表是一种物理存储(内存)单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过对象引用来实现的。

•链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点的引用。

2.单链表

单链表有一个引用指向后续节点。

在这里插入图片描述
在这里插入图片描述

data为数据,next为指向下一个节点的引用

链表PHP模拟DEMO
class node{
	public $data;
	public $next;
}
class LinkList{
	public header;
	private size;
}	//操作函数getSize(),setHeader($v),__construct(),add($d)
//	   delete($d),update($old,$new),find($d),getAll()

3.双向链表

双向链表有两个引用分别指向前后节点。优势方便向前查询数据。

在这里插入图片描述
在这里插入图片描述

data为数据,pre为指向前个节点的引用,next为指向后个节点的引用。

链表PHP模拟DEMO
class node{
	public $data;
	public $prev;
	public $next;
}
class doubleLinkList{
	public header;
	private size;
}	//操作函数getSize(),setHeader($v),__construct(),add($d)
//	   delete($d),update($d),find($d),

4.循环链表

循环链表即单链表最后一个引用指向第一个节点。
在这里插入图片描述
在这里插入图片描述

约瑟夫环
圣夏彤 邴丹丹 台浩邈 鲜依瑶 闪又青 威心远 佛乐正 寻仙韵 别光华 柳舒兰 
闻清婉 让昕珏 出欣跃 慎诗丹 卿冬萱 拜若薇 黄梦秋 浮娅玟 骆飞章 剑成化 
平海荣 望凡霜 蔡雪萍 姓慧颖 秋访梦 须盈秀 邰宣朗 林安彤 谬祺然 能骏琛 
汤香菱 查寻琴 乾问凝 冒听筠 左诗兰 市暄美 位水丹 裔翠芙 邗宏博 空永长 
进南霜 司空新雪 穆乐蓉 绪野雪 告天瑞 仁桂帆 齐珠雨 姒以冬 禽夏菡 呼延兰英 
简小雨 建彤蕊 偶迎南 南夏岚 枝傲菡 罗蔚星 年博简 夔代巧 戈曼蔓 赫麦冬 
光美如  戏柔惠 恭千秋 森寄蕾 亓娴淑 豆飞瑶 菅尔容 斋依云 荆紫杉 宦雪容 
酒含景 占碧蓉 牵盼香 唐青雪 清映秋 瑞和璧 蓝听春 牛新洁 沐妙思 胥雍恬 
饶鸿光 丹乐然 抄曼吟 张廖智杰 府念云 昔德宇 尧平安 尹芳泽 勤清妍 哀清莹 
柴佩珍 夹谷昆琦 塔思琪 虞采萱 融水荷 招采萱 势鸿志 次长岳 费莫怀芹 始修真

n个小孩坐在一圈,每数到3就退出去,最后余下的是谁?

用循环链表做。

$count = 1;
$list = $this->head;
while($list->next != $list){
    if($count%3==2){
        $list->next=$list->next->next;
    }else{
        $list=$list->next;
    }
    $count++;
}
echo $list->name;

5.数据结构队列

•队列是一种特殊的线性表(链表),特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作(FIFO),和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

•队列中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。

在这里插入图片描述

队列的PHP代码
class node{
	public $data;
	public $next;
}	
class Queue{
	public $head;
	public $last;
	public $size;
}	//操作函数getSize(),__construct(),enqueue($d)
//	   dequeue(),getAll()

6.队列的应用

•银行排队系统

•n个整数,最少选几个数,使和不小于s (穷举o(n^2),用队列的o(n))

•在PHP中建议使用Spl库SplQueue

PHP 栈使用

1.栈的概念

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

栈的PHP实现DEMO

1.定义node,设置属性data,prev

2.定义stack类,设置栈顶top,size

3.编写出栈push(),pop()函数

4.返回栈所有数据函数getAll()

5.最后我们使用栈来解决 匹配括号 应用

栈应用 进制转换

•我们使用栈演示如下功能:

•十进制转八进制

•十进制转十六进制

栈应用 走迷宫
 /*     迷宫数组     1表示墙     0表示路     */  
    $maze = [ 
        [1,1,1,1,1,1,1,1,1,1],  
        [1,0,0,1,0,0,0,1,0,1],  
        [1,0,0,1,0,0,0,1,0,1],  
        [1,0,0,0,0,1,1,0,0,1],  
        [1,0,1,1,1,0,0,0,0,1],  
        [1,0,0,0,1,0,0,0,0,1],  
        [1,0,1,0,0,0,1,0,0,1],  
        [1,0,1,0,0,0,1,1,0,1],  
        [1,1,0,0,0,0,0,0,0,1],  
        [1,1,1,1,1,1,1,1,1,1],  
    ];

树结构与二叉树

1.树的定义

•树状图是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
在这里插入图片描述

2.树的相关述语

•结点:树的结点包含一个数据元素和若干指向其子树的分支

•结点的度(Degree):结点拥有的子树。

•叶子结点(Leaf)/终端结点:度为0的结点。

•分支结点/非终端结点:度不为0的结点。

•内部结点:除根节点以外,分支结点也称为内部结点。

•树的度:树内各结点的度的最大值

在这里插入图片描述
在这里插入图片描述

3.结点之间的关系

•孩子(Child)和双亲(Parent):B 结点是A 结点的孩子,A结点是B 结点的双亲(注意是双亲,不是单亲因为雌雄同体,双亲既是父节点也是母节点,所以称为双亲)

•兄弟(sibling):同一个双亲的孩子之间互称兄弟。

•结点的祖先:从根结点到该结点所经过分支上的所有结点。

•子孙:以某结点为根的子树中的任一结点都称为该节点的子孙。

•无序树和有序树:如果将树中结点的各子树看成从左至右是有次序的,不能互换的,则称该数为有序树,否则为无序树。

•森林(forest):m(m>=0)棵互不相交树的集合。
在这里插入图片描述

1.双亲表示法

以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点到链表或数组中的位置。

2.孩子表示法

把每个结点的孩子结点排列起来,以单链表作为存储结构,则n个结点有n个孩子链表,如果是叶子结点则此单链表为空。然后n个头指针又组成一个线性表,采用顺序存储结构,存放进一个一维数组中。

3.双亲孩子表示法

比孩子表示法,多一个父亲指针。

4.孩子兄弟表示法

1.任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟存在也是唯一的。因此,设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟。

常用排序算法

排序算法

•冒泡排序(Bubble sort)

•选择排序 ( Selection Sort )

•插入排序(Insertion sort)

•快速排序 ( Quick sort )

排序算法的稳定性

•假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,Ai=Aj,且Ai在Aj之前,而在排序后的序列中,Ai仍在Aj之前,则称这种排序算法是稳定的;否则称为不稳定的。

•$arr = [ 9, 4, 6, 8, 17,12,44,12,56,71,21,19,81,99];

• 0 1 2 3 4 5 6 7 8 9 10 11 12 13

冒泡排序

•冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

•特点,就是第一次的时候最大的元素到最后面。
在这里插入图片描述

选择排序

•选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

插入排序

•插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

快速排序

•快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

排序算法

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值