数组、排序、查找
数组:可以用于存放多个数据的数据类型。
一维数组的创建
Php中的数组是一组关键字和值的集合,值可以是任何一种类型;
创建数组:
第一种方法:
//<?php
$arr[0]=123;
$arr[1]=”abc”;
$arr[2]=true;
$arr[3]=2.3;
$arr[4]=null; //放置null:空,不会打印出来,但还是占用一个空间,算数组中一个元素
//遍历一下数组
For($i=0;$i
Echo’
’.$arr[i];
}
/?>
几个概念:
[0]--à称为下标,或者关键字;
$arr[0]--à称为数组的一个元素;
$arr-----à称为数组的名称;
在php中元素存放的值可以是任意数据类型;
第二种方法:
语法:$数组名=array[值……]
$arr=array[1,9,”hello”,4.5]
For($i=0;$i
Echo”
”.$arr[$i];
}
第三种方法:
在默认情况下,元素的下标是从0开始编号,但实际上也可以自己指定关键字;
语法:array(key=>value,……)
///键(key)可以是一个整数,字符串;
///value可以是任意类型的值。
$arr[‘logo’]=”北京”;
$arr[‘lsg’]=123;
$arr[4]=678;
或者:
$arr=array(“logo”=>”北京”,”lsg”=>123,4=>678)
两者是一样的!
遍历的时候要这样: (这里用for遍历是不行的)
Foreach($arr as
$key=>$val){ (foreach的使用范围更广)
Echo $key.”=”.$val.”
”;
}
打印结果是:
Logo=北京
Lsg=123
4=678
注意:
①
如果创建一个数组的时候,没有对某个元素指定键名(下标),则php会自动取当前最大的那个下标值(整数),加上一作为该元素的下标(关键字)。例如:
$arr=array(5=>”logo”,456,789);
$arr[5]=”yes”; ///这里yes会把logo覆盖掉,体现出替换数组中的某个元素;
Echo $arr[5];
///要访问logo这个值;
Echo
‘
’.$arr[6] //访问456这个值;
② 如果给出的某个元素的下标一样,则会覆盖原来的值;(也就是替换)
③ 如果使用true作为键名,将使integer 1
成为键名;
使用false作为键名;将使integer 0 作为键名;
使用null作为键名将等同于使用空字符串。
使用空字符串作为键名将新建(或覆盖)一个用空字符串作为键名的值,这和用空的方括号不一样。
使用小数作为key将自动截断小数部分;
不能用数组和对象作为键(key),这样做会导致一个警告:lllegal offset
type。
访问方法:
$arr[true]=”hello”; //è等价于$arr[1]
$arr[false]=”world”; ///è等价于$arr[0]
$arr[null]=”北京”; //è等价于$arr[null]或者$arr[“”]
$arr[123.45]=”haha”; //è等价于$arr[123]
① 通常我们可以使用print_r($arr)或var_dump($arr)来显示整个数组的情况,后者显示的更详细;
② 访问数组的时候下标不要越界,不然会出一个notice;
一维数组的引用:
数组的引用(使用):数组名[key值]
如果你写的键值不存在,则会报错。
$a=array(2,3);
$a[2]=45; /=è这里赋值:$a[3]=12echo
$a[3]也是可以输出的,但$a[2]则会出错
Echo
$a[2];
输出:45
Php数组的特点:说明在php中数组是可以动态增长的。
一维数组的引用陷阱:
$arr[bar]=”hello,world!”;
Echo $arr[bar];
这样使用是危险的!
l Php数组中的几个重要函数:
① 使用count($arr)函数统计数组条数(里元素的个数);
② 使用is_array($arr)函数判断是不是数组;
③ Print_r()和var_dump()【同时显示数据类型】可以显示数组;
④ 拆分字符串:explode(“按照什么拆分”,字符串);
⑤ Sort()函数用于排序【看文档】;
数组的遍历:
可以使用for循环,while循环,do while循环(这里的数组的下标是从0开始顺序排列)
最巧妙的一种遍历数组的方法是使用foreach:(这里的下标不受限制)
Foreach( $arr as $key=>$value
){ // as => 是不能变的!
…….
}
l 删除数组的某个键值:
Unset()函数允许删除数组中的某个键(即可以销毁某个元素,也可以销毁某个变量),但要注意,数组将不会重建索引。
$arr[0]=12;
$arr[1]=34;
$arr[2]=”hello”;
现在要删除$arr[1]这个元素:
Unset($arr[1]);
******删除$arr[1]后,不会对数组重新建立索引,即剩余的键(下标)不会有变化。
数组运算符:(了解)
+
运算符是把“+”右边的数组元素(除去键值与“+”左边的数组元素相同的那些元素)附加到左边的数组后面,但是重复的键值不会被覆盖。例如:
$a = array(“a”=> “apple”, “b” =>
“banana”);
$b = array(“a”=> “peat”, “b”=>
“strawberry”, “c”=>”cherry”);
$c = $a + $b ;
则$c的“a”、“b”不会变,只是把“c”的值和下标放到$a的后面,$a元素个数变为3
一维数组小结
① 数组可以存放任意类型的数据;
② 数组大小不必事先确定,可以实现动态增长;
③ 数组名可以理解为指向数组首地址的引用;
④ 数组中的元素以key=>value的形式存在;
⑤ 如果没有给数组指定key,则取当前最大的整数索引值,而新的键名将是该值加1.
数组的排序
这里学习一些常用的排序方法
① 冒泡法;
② 选择排序法;
③ 插入排序法;
④ 快速排序法;
排序是将一组数据依照指定的顺序进行排列的过程。
排序分类:两类
① 内部排序;
指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择式排序法、插入式排序法);
② 外部排序法;
数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法);
排序(sorting)是数据处理的一种很重要的运算,同时也是很常用的运算,一般数据处理工作25%的时间都在进行排序。简单的说,排序就是把一组记录(元素)按照某个域的值的递增(即由大到小)或递减(由小到大)的次序重新排列的过程。
交换式排序法:
属于内部排序法,是运用数据值比较后,依据判断规则对数据位置进行交换,以达到排序的目的。
交换式排序分为两种:
1、 冒泡排序法(bubble sort);
2、 快速排序法(quick sort)。
冒泡排序法:
基本思想是:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的排序码,若发现逆序则交换,使排序码较小的元素逐渐从后部移向前部(从下标较大的单元移向小标较小的单元),就像水底的气泡一样逐渐向上冒。
因为排序过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换,从而减少不必要的比较。
案例1:
//<?php
//简单的
$arr=array(0,5,-1);
//这是一个中间变量;
$temp=0;
//把数组从小到大排列
//外层循环
for($i=0;$i
for($j=0;$j
//前面的数比后面的数大,就要交换
if($arr[$j]>$arr[$j+1]){
$temp=$arr[$j];
$arr[$j]=$arr[$j+1];
$arr[$j+1]=$temp;
}
}
}
//输出
print_r($arr);
//?>
结果:Array ( [0] => -1 [1] => 0 [2]
=> 5 )
可以把冒泡法封装成一个函数:
//<?php
//封装冒泡法函数
function bubbleSort(&$arr){
//这是一个中间变量;
$temp=0;
//把数组从小到大排列
//外层循环
for($i=0;$i
for($j=0;$j
//前面的数比后面的数大,就要交换
if($arr[$j]>$arr[$j+1]){
$temp=$arr[$j];
$arr[$j]=$arr[$j+1];
$arr[$j+1]=$temp;
}
}
}
}
$myarr=array(0,5,-1,54,-2.3,12);
//使用函数输出;
bubbleSort($myarr);
print_r($myarr);
//?>
输出结果:Array ( [0] => -2.3 [1] => -1
[2] => 0 [3] => 5 [4]
=> 12 [5] => 54 )
注意:数组默认传递的是值,而不是地址(对象默认传递的是地址!)!
选择式排序法:
选择式排序属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,经过和其他元素重整,再依原则交换位置后达到排序的目的。
选择式排序有可分为两种:
① 选择排序法(selection sort);
② 堆排序法(heap sort);
选择排序法:也是一种简单的排序方法,基本思想是:第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第二次从R[1]~R[n-1]中选取最小值,与R[1]交换,第三次从R[2]~R[n-1]中选取最小值,与R[2]交换,。。。。。。第i次从R[i-1]~R[n-1]中选取最小值,与R[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排序的有序序列。
选择排序法:
//选择排序法
function selectSort(&$arr){
$temp=0;
for($i=0;$i
//假设$i就是最小的数;
$minVal=$arr[$i];
//记录认为的最小数的小标
$minIndex=$i;
for($j=$i+1;$j
//说明我们认为的最小值不是最小值
if($minVal>$arr[$j]){
$minVal=$arr[$j];
$minIndex=$j;
}
}
//最后交换
$temp=$arr[$i];
$arr[$i]=$arr[$minIndex];
$arr[$minIndex]=$temp;
}
}
$myarr=array(0,5,-1,45,-12);
//使用选择排序函数输出;
selectSort($myarr);
print_r($myarr);
输出结果:Array ( [0] => -12 [1] => -1
[2] => 0 [3] => 5 [4]
=> 45 )
插入排序法:有三种① 插入排序法(insertion sort)② 谢耳排序法(shell sort)③
二叉树排序法(binary-tree sort)
主要学插入排序法
基本思想:把n个待排序的元素看成一个有序表和无序表,开始时有序表中只包含一个元素,无序列表中包含一个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。
//<?php
//插入排序法
function insertSort(&$arr){
//先默认下标是0的这个数是有序的,所以从1开始
for($i=1;$i
//$insertVal是准备插入的数
$insertVal=$arr[$i];
//准备先和下标是$insertIndex的元素比较
$insertIndex=$i-1;
//如果这个条件满足,说明还没有找到适当的位置
while($insertIndex>=0&&$insertVal
//满足该条件时,把该数后移
$arr[$insertIndex+1]=$arr[$insertIndex];
//循环
$insertIndex--;
}
//这是已经找到适当的位置,则插入(这里可以继续优化!)
$arr[$insertIndex+1]=$insertVal;
}
}
$myarr=array(0,5,-1,45,-12);
//使用插入法排序
insertSort($myarr);
print_r($myarr);
//?>
输出结果:Array ( [0] => -12 [1] => -1
[2] => 0 [3] => 5 [4]
=> 45 )
快速排序法:基本思想:
特点:
当数据量很大时,可以快速的排列,得出结果;是这几种排序法中速度最快的一种方法;
缺点:占用内存大;
//<?php
function quickSort($left,$right,&$array){
$l=$left;
$r=$right;
$pivot=$array[($left+$right)/2];
$temp=0;
while($l
while($array[$l]
while($array[$r]>$pivot) $r--;
if($l>=$r) break;
$temp=$array[$l];
$array[$l]=$array[$r];
$array[$r]=$temp;
if($array[$l]==$pivot) --$r;
if($array[$r]==$pivot) ++$l;
}
if($l==$r){
$l++;
$r--;
}
if($left
if($right>$l) quickSort($l,$right,$array);
}
//快速排序法
$array=array(-9,78,0,23,-567,89);
quickSort(0,count($array)-1,$array);
print_r($array);
//?>
输出结果是:Array ( [0] => -567 [1] =>
-9 [2] => 0 [3] => 23 [4]
=> 78 [5] => 89 )
查找:
学习两种:
1、 顺序查找:对某个数组,按顺序一个一个比较,找到想要的数据;
案例:要求从一组数据中查找一个数,如果找到则输出该数的下标,找不到则输出查无此数;
//<?php
$arr=array(45,90,700,0,-1);
function search(&$arr,$findVal){
$falg=false;
for($i=0;$i
if($findVal==$arr[$i]){
echo"找到了,下标为=".$i;
$flag=true;
break;//(只找一个时break,找多个不要)
}
}
if(!$flag){
echo"查询不到";
}
}
search($arr,0);
//?>
输出:找到了,下标为=3
2、
二分查找(掌握)
前提:该数组本身已经是一个有序数组,如果该数组不是有序的,则必须先排序,再查找。
思路:首先找到数组中的中间这个数,然后与要查找的数比较,如果要查找的数大于中间这个数,则说明应该向后找,否则,向前找;如果相等,则说明找到了。
//二分查找
//<?php
function
binarySearch(&$arr,$findVal,$leftIndex,$rightIndex){
//当$rightIndex>$leftIndex说明没有这个数;
if($rightIndex
echo"找不到该数";
return;
}
//找到中间这个数
$middleIndex=round(($rightIndex+$leftIndex)/2);
//如果大于中间这个数,则向后面找(递归)
if($findVal>$arr[$middleIndex]){
binarySearch($arr,$findVal,$middleIndex+1,$rightIndex);
}
//如果小于中间这个数,则向前面找(递归)
else if($findVal
binarySearch($arr,$findVal,$leftIndex,$middleIndex-1);
}else{
echo"找到了这个数,下标是=".$middleIndex;
}
}
$arr=array(-15,-10,0,20,200,250,255);
binarySearch($arr,250,0,count($arr)-1);
//?>
输出结果是:找到了这个数,下标是=5
多维数组(只学习二维的数组):
1、 定义:
语法:$a=array(array(),array()……)
例如:$a=array(array(1,2),array(5,0));
2、二维数组在内存中的存放:
2、 用处:地图等有纵横坐标的地方;
案例:
//<?php
//定义二维数组
$arr=array(
array(1,2,3,1,2),
array(1,2,3,1,2,0,0),
array(1,2,3,1,2,8,6),
array(1,2,3,1,2,5),);
//遍历每行
for($i=0;$i
//遍历每行的元素
for($j=0;$j
echo $arr[$i][$j]." ";
}
echo "
";
}
echo "
".$arr[3][4];
//?>
输出:
1 2 3 1 2 1 2 3 1 2 0 0 1 2 3 1 2 8 6 1 2 3 1 2 5 2练习:矩阵转置------------行列互换!