11 数组

数组的分类、定义

索引数组(就是js数组的下标情况嘛,下标为从0开始的连续整数)、关联数组、混合数组
数组定义有很多种方法,都是小问题啦。

数组定义.PNG

要注意的是,php数组的元素顺序,和下标没有任何关系!只与放入的顺序有关!

数组的基本使用

1.求一维数组的平均值;求二维数组平均值也类似

//1.求一维数组的平均值

2.求一维数组的最大值及其下标

//求一维数组的最大值(索引数组)
$arr2 = array(3, 11, 1, 4, 23, 19);
$max = $arr2[0];
$pos = 0;
for($i = 1; $i < count($arr2); $i ++){
    if($max < $arr2[$i]){
        $max = $arr2[$i];
        $pos = $i;
    }
}
echo "最大值为$max";
echo "下标为$pos";


数组的遍历

1.foreach基本语法

for($数组变量名 as $key => $value){
    //$key => 可省略
    //循环体可以使用 $key 和 $value
    //总从数组的开头往后取数据
}

2.指针操作及遍历原理

  • 默认情况下,数组指针指向数组第一个单元
  • 数组有关单元的操作,如果没有指定下标,就是对该数组指针所对应单元的操作

所谓遍历,其实就是指针一次次地下移,且一次次地取键和值。数组作为一个总体数据,有以下这些指针操作函数:

//1.获得数组当前指针所在单元的值
$v1 = current($arr);

//2.获得数组当前指针所在单元的键
$v2 = key($arr);

//3.先将数组的指针移到下一个,然后取新的单元的值
$v3 = next($arr);

//4.先将数组的指针移到上一个,然后取新的单元的值
$v4 = prev($arr);

//5.先将数组的指针移到最后一个单元,然后取该单元的值
$v5 = end($arr);

//6.重置数组的指针重置到第一个单元,然后取该单元的值
$v6 = reset($arr);

3.for + next 遍历数组

对php数组,不能单纯用for循环遍历,for循环只能遍历索引数组呢。对于不是索引数组地数组,要用for循环来遍历地话,要配合next来使用

$arr = array(1=>3, "a"=>5, 10=>22, "abc"=>9);
for($i = 0; $i < count($arr); $i ++){
    $k = key($arr);
    $v = current($arr);
    echo $k . "=" . $v . "
"; //将指针下移 next($arr); }

4.while + each() + list()遍历数组

each()的作用:
先取数组当前单元的下标和值,并放到一个数组里,然后将指针移到下一位。

each().PNG

list()的作用:
一次性取得一个数组中,从0开始的多个数字下标的单元的值
$list($变量1, $变量2, $变量3, ...) = $数组,如果某个变量对应的下标没有相应的数组元素,会报错的。{比如$list($v1, $v2, $v3)=$arr,而数组$arr中没有下标为2的元素,则会报错 }

$arr = array(1=>3, "a"=>5, 10=>22, "abc"=>9, 0=>12);
list($v1, $v2) = $arr;
echo $v1 . "和" . $v2;    //12、3

while + each() + list() 组合使用遍历
这个写法的作用和foreach完全一样,所以学这个干啥?

while(list($key, $value)=each($arr)){
    echo "$key=>$value";
}

5.foreach的一些细节

  • 从php7开始,foreach不再对数组内部指针起作用,指针不会再移动了,永远在初始状态
  • foreach也是正常的循环语法,break、continue等也是起同样的作用的
  • 遍历过程中,值变量的默认传递方式是值传递
  • 遍历过程中,值变量传递方式可以设置成引用传递,加上 &
    $arr = array(1=>3, "a"=>5, 10=>22, "abc"=>9, 0=>12);
    foreach($arr as $key => &$value){
      $value = $value *2;    //改变值
      echo "$key : $value 
    "; } print_r($arr); //输出数组的值确实较之前改变了
  • 键变量不可引用传递
  • foreach默认在原数组上进行遍历;若果遍历过程中对数组进行某种修改、或者某种指针性操作,则会复制数组后再复制出来的数组上进行遍历(即即使在遍历过程中对数组进行修改,但是遍历过程还是按原来的数组来走,不受影响
$arr = array(1=>3, "a"=>5, 10=>22, "abc"=>9, 0=>12);
foreach($arr as $k => $v){
    echo "$k=>$v 
"; if($k === 10){ $arr[99] = '新的数据项'; //添加一个新项到数组末尾 //但新项在这次遍历中不会出现 } } //1=>3 a=>5 10=>22 abc=>9 0=>12
  • 若果值变量是引用传递,则遍历无论如何都会在原数组上进行。
$arr = array(1=>3, "a"=>5, 10=>22, "abc"=>9, 0=>12);
foreach($arr as $k => &$v){
    echo "$k=>$v 
"; if($k === 10){ $arr[99] = '新的数据项'; //添加一个新项到数组末尾 //新项在这次遍历中会出现! } } //1=>3 a=>5 10=>22 abc=>9 0=>12 99=>新的数据项


数组排序函数

1.sort()

将数组的值从小到大排列,并且下标全部改为索引下标

2.asort()

将数组的值从小到大排列,下标不会变

3.rsort()

从大到小排,下标不保持

4.arsort()

从大到小拍,下标保持不变

5.ksort()

按键名从小到大排

6.krsort()

按键名从大到小排

(更多见手册啦)

冒泡排序算法

$arr = array(5, 1, 7, 6, 2);
//对数组 $arr 进行冒泡从小到大排序
for($i = 0; $i < count($arr) - 1; ++ $i){//需要进行 count($arr)-1 趟比较
    for($k = 0; $k < count($arr) - 1 - $i; ++ $k){//每趟需要比较的次数
        //把$k当作下标来使用
        if($arr[$k] > $arr[$k + 1]){
            //进行交换
            $t = $arr[$k];
            $arr[$k] = $arr[$k + 1];
            $arr[$k + 1] = $t;
        }
    }
}
print_r($arr);


选择排序算法

$arr = array(3, 5, 22, 9, 12);
$n = count($arr);
//对数组 $arr 进行冒泡从小到大排序
for($i = 0; $i < $n - 1; ++ $i){//需要进行 count($arr)-1 趟交换
    //每趟都要求出剩余数据中的最大值单元
    $max = $arr[0];
    $pos = 0;
    for($k = 0; $k < $n - $i; ++ $k){//每趟的数据 count($arr) - $i
        if($arr[$k] > $max){
            $max = $arr[$k];
            $pos = $k;
        }
    }
    //每一趟都要进行交换,将最大值单元交换到剩余数据末位
    $t = $arr[$pos];
    $arr[$pos] = $arr[$n - $i - 1];
    $arr[$n - $i - 1] = $t;
}
print_r($arr);

数组二分查找算法

  • 针对索引数组
  • 针对已经排好序的数组(一般从小到大)
  • 效率非常高,即使几十亿的数据,也仅仅需要约30次就能找出来了
//已经sort好的数组
$arr = array(3, 5, 9, 12, 14, 21, 33, 35, 39, 41, 45, 57, 67, 78, 87, 91, 95, 96, 233, 455, 655, 677, 689);
//查找数组中有没有33这个项
$search = 1;
$len = count($arr); //数组长度

//函数功能:在数组$array的$begin到$end位置之间找$target,返回到底有没有$target
function binary_search($array, $target, $begin, $end){
    //若果位置不合法,则不进行查找
    if($end < $begin){
        return "不存在";
    }
    //位置合法,进行查找
    $mid = floor(($begin + $end)/2);    //向下取整,得中间位置
    $mid_val = $array[$mid];
    if($mid_val == $target){
        return "存在";
    }
    else if($mid_val > $target){
        //中间项比目标大,则继续往中间项的左边找
        $result = binary_search($array, $target, $begin, $mid-1);
    }
    else{
        //中间项比目标小,则继续往中间项的右边找
        $result = binary_search($array, $target, $mid+1, $end);
    }
    return $result;
}

//运行函数
//在数组$arr中查找$search,在其全部位置中找(0到$len-1)
$v = binary_search($arr, $search, 0, $len-1);
echo $v;

你可能感兴趣的:(11 数组)