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);
?>


執行效率:插入算法>選擇算法>冒泡算法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章