php数据结构课程---3、队列(队列实现方法)

php数据结构课程---3、队列(队列实现方法)

一、总结

一句话总结:

1、数据实现:适用于功能不复杂的情况
2、链表实现:受限链表,只能队头队尾操作:适用于功能复杂情况

1、队列的数组实现注意点?

array_push() + array_shift()
shift: [ʃɪft] :v. 转移;去除(污迹);n. 转移;改变

shift

英 [ʃɪft]  美 [ʃɪft] 
  • v. 转移;快速移动;变换;改变观点;推卸(责任);振作;移位;狼吞虎咽地吃;去除(污迹);销售,出售;换挡;轮班;含糊其辞,拐弯抹角
  • n. 转移;改变,转变;手段;轮班;轮班职工;转换(键);(直筒式)连衣裙,内衣;计谋,诡计
 1 数组实现队列
 2 $arr = [];
 3 array_push($arr,"张三");
 4 array_push($arr,"李四");
 5 array_push($arr,"王五");
 6 array_push($arr,"王六");
 7 
 8 while($data  = array_shift($arr)){
 9     echo $data."<br>";
10 }

2、队列的链表实现的注意点?

链表实现的队列可以增加各种函数来实现复杂操作
普通单链表结构 + push函数和shift函数
<?php 

class Node{
    public $data;
    public $next;

    public function __construct($data,$next=null){
        $this->data = $data;
        $this->next = $next;
    }
}


class Queue{
    public $front = null;
    public $rear = null;

    public $size = 0;

    public function __construct(){

    }

    public function push($data)
    {
        $n = new Node($data);
        if($this->front == null && $this->rear == null){
            $this->front = $n;
            $this->rear = $n;
        }else{
            $this->rear->next = $n;
            $this->rear  = $n;
        }
        $this->size++;
    }

    public function shift()
    {
        if($this->front){
            $this->size--;
            $data = $this->front->data;
            $this->front = $this->front->next;
            return $data;
        }else{
            return null;
        }
    }

}

// $s = new Queue();
// $s->push("aaaa");
// $s->push("bb");
// $s->push("cc");
// $s->push("dd");
// $s->push("fifo");

// // echo $s->shift();

// while($data = $s->shift()){
//     echo $data."<br>";
// }

3、在php中使用队列适合用什么?

在PHP中建议使用Spl库SplQueue(注意不是sql)
 1 <?php
 2   
 3 $queue = new SplQueue();
 4 $queue->enqueue('A');
 5 $queue->enqueue('B');
 6 $queue->enqueue('C');
 7 
 8 $queue->rewind();
 9 while($queue->valid()){
10     echo $queue->current(),"
";
11     $queue->next();
12 }
13 
14 print_r($queue);
15 $queue->dequeue(); //remove first one
16 print_r($queue);
17 
18 ?>
19 Output
20 
21 A
22 B
23 C
24 SplQueue Object
25 (
26     [flags:SplDoublyLinkedList:private] => 4
27     [dllist:SplDoublyLinkedList:private] => Array
28         (
29             [0] => A
30             [1] => B
31             [2] => C
32         )
33 
34 )
35 SplQueue Object
36 (
37     [flags:SplDoublyLinkedList:private] => 4
38     [dllist:SplDoublyLinkedList:private] => Array
39         (
40             [0] => B
41             [1] => C
42         )
43 
44 )

4、php中统计算法执行时间的方法及函数?

microtime():其实超好记,其实不用记,时间函数是time(),计算程序时间肯定是微秒级的,微秒函数肯定是microtime()
$begin = microtime();
算法段...
$end = microtime()-$begin;

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

暴力:就是双重循环
队列(感觉不是很好,用优先队列取前几个比较好o(nlogn)):如果和不够,就增加队列中的元素,如何和够了,就减去队列之前的元素。队列中的元素的个数差不多就是结果(这样算有问题,只能得到近似解,难道最大的几个数一定在数组的某一段上么)
总结:普通队列能有什么东西,入队,出队,以及队列中的个数,仅此而已

暴力:

<?php 
// n个数列,最少选几个数,使和大于s,队列算法 o(n^2)
$arr=[];

$sum = 0;
$max = 10000;
$min = 100;
$s= 2500;
$count = 0;

//随机生成10000个数
for ($k=0; $k < $max ; $k++) { 
    $arr[] = rand(0,1000);
}
$begin = microtime();

//两层for循环暴力穷举搜索结果
for ($i=0; $i <$max ; $i++) { 
    $sum=$arr[$i];
    for ($j=$i+1; $j <$max; $j++) { 
        $count++;
        if($sum<=$s){
            $sum+=$arr[$j];
        }else{
            $min=min($j-$i,$min);
            break;
        }
    }
}
$end = microtime()-$begin;

echo "暴力穷举法 最少选择 $min 个数字,耗时 $end 毫秒,共执行 $count 循环。";

队列:

<?php 
// n个数列,最少选几个数,使和大于s,队列算法 o(n)

$arr=[];

$sum = 0;
$max = 10000;
$min = 100;
$count = 0;
$s= 2500;
$i = 0;
$j = 1;

//随机生成10000个数字
for ($k=0; $k < $max ; $k++) { 
    $arr[] = rand(0,1000);
}
$queue = [];


$begin = microtime();
$sum+=$arr[$i];
//当没有达到$max这个遍历次数时
while($i<$max && $j<$max){
    $count++;
    //如果当前和小于所求
    if($sum<=$s){
        // array_push($queue,$arr[$j]);
        $sum+=$arr[$j];
        $j++;
    }else{
        //如果当前和大于所求
        $min=min($j-$i,$min);
        // array_shift($queue);
        $sum-=$arr[$i];
        $i++;
    }
}
$end = microtime()-$begin;
echo "使用队列 最少需要选择 $min 数字, 耗时 $end 毫秒,共执行 $count 次!";

6、如何快速判断函数功能:或者说算法作用?

打印中间变量

最简单实例:比如n个整数,最少选几个数,使和不小于s (穷举o(n^2),用队列的o(n)) 的队列实现,最开始可以只选3个数

二、内容在总结中

n个整数,最少选几个数,使和不小于s (穷举o(n^2),用队列的o(n)) 的队列实现测试代码

    //测试队列:n个数列,最少选几个数,使和大于s,队列算法 o(n)
    public function test_queue()
    {
        // n个数列,最少选几个数,使和大于s,队列算法 o(n)

        $arr=[];

        $sum = 0;
        $max = 6;
        $min = 6;
        $count = 0;
        $s= 80;
        $i = 0;
        $j = 1;

        //随机生成10000个数字
        for ($k=0; $k < $max ; $k++) {
            $arr[] = rand(0,100);
        }
        $queue = [];

        dump($arr);

        echo "sum:{$sum}<br>";
        echo "arr[i]:{$arr[$i]}<br>";
        $begin = microtime();
        $sum+=$arr[$i];
        //当没有达到$max这个遍历次数时
        while($i<$max && $j<$max){
            $count++;
            //如果当前和小于所求
            if($sum<=$s){
                // array_push($queue,$arr[$j]);
                $sum+=$arr[$j];
                echo "---sum<=s---<br>";
                echo "sum:{$sum}<br>";
                echo "arr[j]:{$arr[$j]}<br>";
                echo "i:{$i}<br>";
                echo "j:{$j}<br>";
                $j++;
            }else{
                //如果当前和大于所求
                echo "---else---<br>";
                echo "sum:{$sum}<br>";
                echo "arr[i]:{$arr[$i]}<br>";
                echo "i:{$i}<br>";
                echo "j:{$j}<br>";
                $min=min($j-$i,$min);
                echo "min:{$min}<br>";
                // array_shift($queue);
                $sum-=$arr[$i];
                $i++;
            }
            echo "-sum:{$sum}<br><br>";
        }
        $end = microtime()-$begin;
        echo "使用队列 最少需要选择 $min 数字, 耗时 $end 毫秒,共执行 $count 次!<br>";
    }

测试的中间结果示例

array(6) {
  [0] => int(56)
  [1] => int(3)
  [2] => int(68)
  [3] => int(66)
  [4] => int(99)
  [5] => int(71)
}
sum:0
arr[i]:56
---sum<=s---
sum:59
arr[j]:3
i:0
j:1
-sum:59

---sum<=s---
sum:127
arr[j]:68
i:0
j:2
-sum:127

---else---
sum:127
arr[i]:56
i:0
j:3
min:3
-sum:71

---sum<=s---
sum:137
arr[j]:66
i:1
j:3
-sum:137

---else---
sum:137
arr[i]:3
i:1
j:4
min:3
-sum:134

---else---
sum:134
arr[i]:68
i:2
j:4
min:2
-sum:66

---sum<=s---
sum:165
arr[j]:99
i:3
j:4
-sum:165

---else---
sum:165
arr[i]:66
i:3
j:5
min:2
-sum:99

---else---
sum:99
arr[i]:99
i:4
j:5
min:1
-sum:0

---sum<=s---
sum:71
arr[j]:71
i:5
j:5
-sum:71

使用队列 最少需要选择 1 数字, 耗时 2.2000000000022E-5 毫秒,共执行 10 次!
 
原文地址:https://www.cnblogs.com/Renyi-Fan/p/10873359.html