PHP算法

改自韩顺平老师的算法公开课。

1、单链表。

使用单链表解决水浒英雄排行问题。

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>链表</title>
</head>
<body>
    <h1>水浒英雄排行榜</h1>
    <hr style="width:300px;margin:0;"/>
    <?php
        class Hero{
            public $no; //名次
            public $name;   //名字
            public $nickname;   //外号
            public $next=null;  //链表
            public function __construct($no='',$name='',$nickname=''){
                $this->no=$no;
                $this->name=$name;
                $this->nickname=$nickname;
            }
        }
        //遍历链表
        function showHero($head){
            $cur=$head;
            while($cur->next!=null){
                echo '英雄排名:'.$cur->next->no.'|'.$cur->next->name.'|'.$cur->next->nickname.'<br/>';
                $cur=$cur->next;
            }
        }
        //添加英雄(有顺序)
        function addHero($head,$hero){
            $cur=$head;
            $flag=false;    //表示没有重复编号
            while($cur->next!=null){
                if($cur->next->no>$hero->no){
                    break;
                }elseif($cur->next->no==$hero->no){
                    echo $hero->no.'号位置已经被占领!<br/>';
                    $flag=true;
                }
                $cur=$cur->next;
            }
            if(!$flag){
                $hero->next=$cur->next;
                $cur->next=$hero;
            }
        }
        //删除英雄
        function delHero($head,$no){
            $cur=$head;
            $flag=false;    //假设没有找到
            while($cur->next!=null){
                if($cur->next->no==$no){
                    $flag=true;
                    break;  //找到
                }
                $cur=$cur->next;
            }
            if($flag){
                $cur->next=$cur->next->next;
            }else{
                echo '没有找到要删除的英雄<br/>';
            }
        }
                                                                                  
        //修改英雄
        function updateHero($head,$hreo){
            $cur=$head;
            while($cur->next!=null){
                if($cur->next->no==$hreo->no) break;
                $cur=$cur->next;
            }
                                                                                      
            if($cur->next==null){    //说明没找到要修改的英雄
                echo '您要修改的英雄不存在<br/>';
            }else{
                $cur->next->name=$hreo->name;
                $cur->next->nickname=$hreo->nickname;
            }
        }
                                                                                  
        $head=new Hero();
                                                                                  
        $hero=new Hero(1,'宋江','及时雨');
        addHero($head,$hero);
                                                                                  
        $hero=new Hero(2,'卢俊义','玉麒麟');
        addHero($head,$hero);
                                                                                  
        $hero=new Hero(4,'吴用','智多星');
        addHero($head,$hero);
                                                                                  
        $hero=new Hero(6,'林冲','豹子头');
        addHero($head,$hero);
                                                                                  
        $hero=new Hero(1,'joe','牛人');
        updateHero($head,$hero);
                                                                                  
        delHero($head,9);
                                                                                  
        showHero($head);
    ?>
</body>
</html>

2、循环链表。

使用循环链表解决约瑟夫问题(丢手帕问题)

<?php
        //小孩类
        class Child{
            public $no;
            public $next=null;
                                                                    
            public function __construct($no){
                $this->no=$no;
            }
        }
                                                                
                                                                
        //添加n个小朋友
        function addChild(&$first,$n){
            $cur=null;  //头节点不能修改
            for($i=0;$i<$n;$i++){
                $child=new Child($i+1);
                if($i==0){
                    $first=$child;
                    $first->next=$first;
                    $cur=$first;
                }else{
                    $cur->next=$child;
                    $child->next=$first;
                    $cur=$cur->next;
                }
            }
        }
                                                                
        //遍历所有小孩
        function showChild($first){
            $cur=$first;
            while($cur->next!=$first){
                //显示
                echo '<br/>小孩的编号:'.$cur->no;
                $cur=$cur->next;
            }
            //while循环最后一个节点没有打印出来
            echo '<br/>小孩的编号:'.$cur->no;
        }
                                                                
        //解决josephu
        function josephu($first,$m,$k){
            $tail=$first;
            $count=0;   //计数器
            while($tail->next!=$first){  //使$tail指向最后一个小孩
                $tail=$tail->next;
            }
            //把first定位的第k个小孩,从第k个小孩数起
            for($i=0;$i<$k-1;$i++){
                $first=$first->next;
                $tail=$tail->next;
            }
                                                                    
            while($tail!=$first){
                $count++;
                //数到$m
                for($i=0;$i<$m-1;$i++){
                    $first=$first->next;
                    $tail=$tail->next;
                }
                echo '<br/>第'.$count.'个出列的小孩是:'.$first->no;
                $first=$first->next;
                $tail->next=$first;
                                                                    
            }
                                                                    
            echo '<br/>最后留在圈子里的人是:'.$tail->no;
        }
                                                                
        $first=null;    //第一个小朋友
        $n=4;   //表示有n个小朋友
        $m=2;   //表示数到m的人出列
        $k=3;   //表示从第k个人开始数
        addChild($first,$n);
        showChild($first);
        josephu($first,$m,$k);
    ?>

3、堆栈

使用PHP对数组模拟出栈、入栈

<html>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8'/>
</head>
<h1>使用数组来模拟栈的各种操作</h1>
<?php
        class MyStack{
                                                      
            private $top=-1;//默认是-1,表示该栈是空的
            private $maxSize=5;//$maxSize表示栈最大容量
            private $stack=array();//
            //入栈的操作
            public function  push($val){
                //先判断栈是否已经满了
                if($this->top==$this->maxSize-1){
                    echo '<br/>栈满,不能添加';
                    return;
                }
                                                          
                $this->top++;
                $this->stack[$this->top]=$val;
            }
                                                  
            //出栈的操作,就是把栈顶的值取出
            public function pop(){
                //判断是否栈空
                if($this->top==-1){
                    echo '<br/>栈空';
                    return;
                }
                                                          
                //把栈顶的值,取出
                $topVal=$this->stack[$this->top];
                $this->top--;
                return $topVal;
            }
            //显示栈的所有数据的方法.
            public function showStack(){
                                                          
                if($this->top==-1){
                    echo '<br/>栈空';
                    return;
                }
                echo '<br/>当前栈的情况是....';
                for($i=$this->top;$i>-1;$i--){
                    echo '<br/> stack['.$i.']='.$this->stack[$i];
                }
                                                          
                print_r($this->stack);
            }
        }
        $mystack=new MyStack;
        $mystack->push('西瓜');
        $mystack->push('香蕉');
        $mystack->push('橘子');
        $mystack->push('柚子');
        $mystack->push('柚子x');
                                                  
        $mystack->showStack();
        $val=$mystack->pop();
        echo '<br/>pop出栈了一个数据'.$val;
        $mystack->showStack();
        $val=$mystack->pop();
        echo '<br/>pop出栈了一个数据'.$val;
        $mystack->showStack();
        $val=$mystack->pop();
        echo '<br/>pop出栈了一个数据'.$val;
        $mystack->showStack();
        $val=$mystack->pop();
        echo '<br/>pop出栈了一个数据'.$val;
        $mystack->showStack();
                                              
?>
</html>

注意$this->stack使用pop出栈后,$this->stack本身并没有改变

4、选择排序算法

<?php
    //选择排序
    function selectSort($arr){
        for($i=0;$i<count($arr)-1;$i++){
            $minValue=$arr[$i]; //假设$arr[$i]为最小值
            $minIndex=$i;   //假设最小值的索引
            for($j=$i+1;$j<count($arr);$j++){
                if($minValue>$arr[$j]){
                    $minValue=$arr[$j];
                    $minIndex=$j;
                }
            }
            //交换
            $temp=$arr[$i];
            $arr[$i]=$arr[$minIndex];
            $arr[$minIndex]=$temp;
        }
        return $arr;
    }
                          
    //测试
    $arr=array(8,-1,6,10);
    $arr=selectSort($arr);
    print_r($arr);
?>

5、冒泡排序算法

<?php
    //冒泡排序算法
    function bubbleSort($arr){
        $count=count($arr);
        if($count<=1) return $arr;
                        
        for($i=0;$i<$count-1;$i++){
            for($j=$count-1;$j>$i;$j--){
                if($arr[$j]<$arr[$j-1]){
                    $temp=$arr[$j];
                    $arr[$j]=$arr[$j-1];
                    $arr[$j-1]=$temp;
                }
            }
        }
        return $arr;
    }
                    
    //测试
    $arr=array(8,-1,6,10);
    $arr=selectSort($arr);
    print_r($arr);
                    
?>

6、插入排序算法

<?php
    //插入排序算法
    function insertSort($arr){
        for($i=1;$i<count($arr);$i++){
            $insertValue=$arr[$i];  //待插入的值
            $insertIndex=$i-1;  //下一步与插入值比较的值的索引
            while($insertIndex>=0&&$insertValue<$arr[$insertIndex]){
                $arr[$insertIndex+1]=$arr[$insertIndex];
                $insertIndex--;
            }
            $arr[$insertIndex+1]=$insertValue;
        }
        return $arr;
    }
    //插入排序法假设数组中只有一个元素,并且是有序的
               
    //测试
    $arr=array(0,5,-1);
    $arr=insertSort($arr);
    print_r($arr);
?>

执行效率:插入算法>选择算法>冒泡算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值