• php实现单,双向链表,环形链表解决约瑟夫问题


    传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季  http://php.itcast.cn

    聊天篇:

    数学对我们编程来说,重不重要?

    看你站在什么样的层次来说. 如果你应用程序开发,对数学要求不高

    但是,如果你开发系统软件,比如(搜索/识别软件[图像,语言识别]/操作系统...)对数学高

    建模.大量数学模型.

    老师啊啊。我是学C++的。麻烦,谈哈对QT和MFC的看法嘛。前景什么的,

    记住 : 打好基础,大有可为!

    初中毕业能去传智学习吗?

    学习It, 不管是java ,php ,c#,对学历要求不高.

    学历不是问题,能力是问题!

    老师听完您的视频可以去找工作吗?

    如果你的自学能力比较强,看完视频可以找份  4000  ,如果你理解的层次比较到位 6000 + 你的表达+英语水平+学历(大专)-> 6500

    8000以上,学习项目[自己去研究一些开源的项目 ec /dedecms/ phpcms ...]

    学习的怎样!!!

    有必要学php又学java吗

    我个人认为,学习好一门,然后再学习其它.

    做架构师,建议多学习是没有害处!


    求学者 (19:54:16)
    我学历低,我英语差,可是看了韩爷就找到工作!很好!

    我是大四毕业生,已经做完你的j2ee校内网了,快要找工作了,面试主要有什么技巧和方法呢?韩爷!

    最好你可以把你项目上线->公网

    面试前,看看传智播客java笔试大全->笔试题oK!

    面试时,不要怕,敢于和面试官交流!===>自信

    这个链表要怎么练习才会比较熟练!~!->多练

    卖油翁的故事!-> 巧是熟练出来 聪明人(举一反三) 笨鸟(举三反一)

    编程

    思想(自己知道怎么做)—(多练习)--->代码(熟练的掌握基本语法)

    老师java程序员以后的发展方向都有哪些?

    1. web程序员->网站应用
    2. 手机开发,安卓开发.

    听的懂 写不了代码啊

    思想---(艰苦练习)--->代码

    约瑟夫问题?

    学以致用!

    学习的套路

    用一个小案例,来学习知识快速入门-->对细节研究--->把一个知识点运用到一个综合案例--->知识点运用到项目中.

    数据库(mysql/oralce)-->思考如果让你去开发一个团购网(数据库的表应该怎么设计.)->看开源项目 (PHP有很多开源项目 discuz  ec dedecms phpcms ) 这样方式成长最快!

    我是大四数学系的学生,自学的PHP,请问韩老师,我毕业到哪类公司实习对自己提高最快呀? =>建议可以到做搜索引擎这方面的公司 , 做系统软件开发(数据库/操作开发/网络安全/识别软件)

    数学+计算机编程

    老师什么时候讲一下CMS吧,对大项目很吃力呀!

    我们传智播客 dedecms 七天 / phpcms / cmstop

    老师android开发容易吗?要怎样入门和深入啊?

    可以看看黎活明老师andriod视频

    大体讲讲老师你学习编程的经历。。。。,没事老师多开几次交流会吧,,数据库的设计太重要了,深有体会?

    大学我们 c/c++ =>五子棋 学习编译原理 PL0编译器,可以完成 if else 和+/-/*/操作 =>基础很好.

    毕业时候.英语学习机()=> 这段时间成长最快 【独立解决问题能力】

    用友开发(vb=>erp)=>点击科技(服务器群集 c/c++/linux/solaris)=>新浪(uc/电子邮件)=>培训06到现在[真正要做什么?] php java

    传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季  http://php.itcast.cn

    u 什么是算法?

    程序=数据结构+算法

    说:我们使用数据结构(int->数组、链表、队列、二叉树,散列...)+ 一些逻辑(if, for , while...) =完成某个任务

    思考: 为什么有些网站可以支持千万以上人来访问? 点击科技和新浪工作.(产品竟开协同软件| 新浪邮件) ->问题?我在公司内部测试一切ok! 登录时候

    解决方法 :首任sina CTO->三天优化. 结论: 程序是有灵魂,就是算法

    百度/google/腾讯/淘宝=>如果不想当一个coder,你一定看算法.[设计模式]/

    u 算法有什么用,在什么地方用?

    提出几个实际的问题?

    <?php

    $str="abc,ytkhello,abc,北京";

    //echo str_replace('abc','传智播客',$str);

         ?>

    你能不能做一个字符串这样的一个数据结构.可以做成:

    试写出用单链表表示的字符串类及字符串结点类的定义,并依次实现它的构造函数、以及计算串长度、串赋值、判断两串相等、求子串、两串连接、求子串在串中位置等7个成员函数。要求每个字符串结点中只存放一个字符。

    比如: 你做一个五子棋游戏:

    这里,如何判断赢,算法, 悔棋算法,接着上局继续玩算法.

    u 再提出一个问题: 约瑟夫问题(丢手帕问题)[最常见一个笔试题.]

    Josephu  问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

        提示:用一个不带头结点的循环链表来处理Josephu 问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。

    直接走代码

    今天我们就要使用 环形链表把这个问题解决.

    总而言之,算法是很重要,是程序的灵魂.

    u 链表-最灵活的数据结构

    什么是链表: 链表是一个有序的列表,但是他在内存中时分散存储的. 使用链表可以解决类似约瑟夫问题, 排序, 索引 ,广义表...

    u 链表的快速入门案例-水浒英雄排行榜管理

    我使用PHP语言来实现, 如果是c#/c/c++/java 思路是完全一样.

    现在我们看看链表是怎样的一种数据结构呢?->内存图:

    我们不让有相同排名的英雄入链表.

    最后的代码 singleLink.php

    <html>

    <head>

    <meta http-equiv="content-type" content='text/html;charset=utf-8'/>

    </head>

    <h1>单向链表完成英雄排行管理</h1>

    <hr/>

    <a href='#'>查询英雄</a>|

    <a href='#'>添加英雄</a>|

    <a href='#'>删除英雄</a>|

    <a href='#'>修改英雄</a>

    <?php

    //首先需要基础知识 。 知道什么是 变量, 有一些面向对象编程基础,

    //知道 if  for while 的语句.

    //定义英雄类

    class Hero{

    //属性

    public $no;//排名

    public $name;//真实名字

    public $nickname;//外号

    public $next=null;//$next是一个引用.指向另外一个Hero的对象实例.

    //构造函数

    public function __construct($no='',$name='',$nickname=''){

    //赋值

    $this->no=$no;

    $this->name=$name;

    $this->nickname=$nickname;

    }

    }

    //因为有些同学,对PHP语法有点不熟.我演示一下

    //创建一个head头,该head 只是一个头,不放入数据

    $head=new Hero();

    //创建一个英雄

    /* $hero=new Hero(1,'宋江','及时雨');

    //连接,使用的是比较二的方法,马上改进

    $head->next=$hero;

    $hero2=new Hero(2,'卢俊义','玉麒麟');

    $hero->next=$hero2;*/

    //写一个函数,专门用于添加英雄.

    function addHero($head,$hero){

    //1.直接在链表最后加.

    //找到链表最后,不能动$head;

    $cur=$head;

    /*while($cur->next!=null){

    $cur=$cur->next;

    }

    //当退出 while循环时,$cur就是链表最后.

    $cur->next=$hero;*/

    //2.按照英雄的排行加入.(这里我希望能够保证链表的顺序)

    //思路:

    $flag=false;//表示没有重复的编号

    while($cur->next!=null){

    if($cur->next->no>$hero->no){

    //找到位置

    break;

    }else if($cur->next->no==$hero->no){

    $flag=true;

    echo '<br/>不能抢位置,'.$hero->no.'位置已经有人了';

    }

    //继续

    $cur=$cur->next;

    }

    // 当退出while时候,位置找到.

    //加入

    //让hero加入

    if($flag==false){

    $hero->next=$cur->next;

    $cur->next=$hero;

    }

    }

    //单链表的遍历怎么做,是从head开始遍历的,

    //$head头的值不能变,变化后就不能遍历我们的单链表

    function showHeros($head){

    //遍历[必须要知道什么时候,到了链表的最后.]

    //这里为了不去改变 $head的指向,我们可以使用一个临时的遍历

    $cur=$head;

    while($cur->next!=null){

    echo '<br/>英雄的编号是'.$cur->next->no.' 名字='.$cur->next->name.' 外号='.$cur->next->nickname;

    //让$cur移动

    $cur=$cur->next;

    }

    }

    //从链表中删除某个英雄

    function delHero($head,$herono){

    //找到这个英雄在哪里

    $cur=$head;// 让$cur指向$head;

    $flag=false;//假设没有找到

    while($cur->next!=null){

    if($cur->next->no==$herono){

    $flag=true;

    // 找到 $cur的下一个节点就是应该被删除的节点.

    break;

    }

    $cur=$cur->next;

    }

    if($flag){

    //删除

    $cur->next=$cur->next->next;

    }else{

    echo '<br/>没有你要删除的英雄的编号'.$herono;

    }

    }

    //修改英雄

    function updateHero($head,$hero){

    //还是还找到这个英雄

    $cur=$head;//$cur就是跑龙套.

    while($cur->next!=null){

    if($cur->next->no==$hero->no){

    break;

    }

    //继续下走.

    $cur=$cur->next;

    }

    //当退出while 后,如果$cur->next==null 说明

    if($cur->next==null){

    echo '<br/>你要修改的'.$hero->no.'不存在';

    }else{

    //编号不能改

    $cur->next->name=$hero->name;

    $cur->next->nickname=$hero->nickname;

    }

    }

    //添加

    $hero=new Hero(1,'宋江','及时雨');

    addHero($head,$hero);

    $hero=new Hero(2,'卢俊义','玉麒麟');

    addHero($head,$hero);

    $hero=new Hero(7,'秦明','霹雳火');

    addHero($head,$hero);

    $hero=new Hero(6,'林冲','豹子头');

    addHero($head,$hero);

    $hero=new Hero(3,'吴用','智多星');

    addHero($head,$hero);

    $hero=new Hero(3,'吴用2','智多星2');

    addHero($head,$hero);

    echo '<br/>************当前的英雄排行情况是*******';

    showHeros($head);

    echo '<br/>************删除后额英雄排行情况是*******';

    //delHero($head,1);

    delHero($head,21);

    showHeros($head);

    echo '<br/>************修改后额英雄排行情况是*******';

    $hero=new Hero(1,'韩顺平','左青龙,右白虎');

    updateHero($head,$hero);

    showHeros($head);

    ?>

    </html>

    传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季  http://php.itcast.cn

    关键是运行,明天我们讲的知识就是用 环形链表解决丢手帕问题.,加深认识.

    现在我们读单链表有了基本的了解.现在在学习一个环形链表

    现在我们来完成约瑟夫问题的解决方案!

    1. Josephu  问题

    Josephu  问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。并求出最后出列的人是哪个?

        提示:用一个不带头结点的循环链表来处理Josephu 问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束

    思路:

    (1) 构建一个环形链表,链表上的每个节点,表示一个小朋友 (PHP语句实现)/c/c++/C#/java

    请发送到我的邮箱 hanshunping@tsinghua.org.cn

    (2) 写一个函数来显示圈圈的所有小孩子.

    关键是你们脑海中,有一个内存分布和运行的大致图.

    (3) 写了一个函数来完成这个游戏.

    (4) 最后的代码:

    <html>

    <head>

    <meta http-equiv='content-type' content='text/html;charset=utf-8'/>

    </head>

    <h1>约瑟夫问题解决</h1>

    <?php

    //1(1) 构建一个环形链表,链表上的每个节点,表示一个小朋友

    //小孩类

    class Child{

    public $no;

    public $next=null;

    //构造函数

    public function __construct($no){

    $this->no=$no;

    }

    }

    //定义一个指向第一个小朋友的引用

    $first=null;

    $n=4000;//$n表示有几个小朋友

    //写一个函数来创建一个四个小朋友的环形链表

    //一会,我们深入的分析&$first时间57:22如果没有&那么就指向堆区的对象,如果有&就保存的是指向对象栈区的变量的地址,是通过栈区的变量去修改的,这里方法里面的变量无法直接联系对象,而是通过指向对象的变量这个代理来修改数据,或者

    //这样理解,两个指向对象的变量是一个克隆关系,同步变化,这就是地址传递。这里要用这个是因为firt是在不断变化。不断变化地指向不同的小孩。

    /**

    addChild函数的作用是: 把$n个小孩构建成一个环形链表,$first变量就指向该

    环形链表的第一个小孩子

    */

    function addChild(&$first,$n){

    //死去活来

    //1. 头结点不能动 $first不能动.

    $cur=null;

    for($i=0;$i<$n;$i++){

    $child=new Child($i+1);

    //怎么构成一个环形链表.

    if($i==0){

    $first=$child;

    $first->next=$child;

    $cur=$first;

    }else{

    $cur->next=$child;

    $child->next=$first;

    $cur=$cur->next;

       

    }

    }

    }

    //遍历所有的小孩,显示,必须把头$first 给函数.

     function showChild($first){

    //遍历 $cur变量是帮助我们遍历环形链表,所以不能动.

    $cur=$first;

    while($cur->next!=$first){

    //显示

    echo '<br/>小孩的编号是'.$cur->no;

    $cur=$cur->next;

    }

    //当退出while循环时,已经到了环形链表的最后,所以还要处理一下最后这个

    //小孩节点

    //显示

    echo '<br/>小孩的编号是'.$cur->no;

    }

    $m=31;

    $k=20;

    //问题简化,从第一个小孩开始数,数2.看看出圈的顺序

    function  countChild($first,$m,$k){

    //思考:因为我们找到一个小孩,就要把他从环形链表删除,

    // 为了能够删除某个小孩,我们需要一个辅助变量,该变量指向的小孩

    //在 $first前面.

    $tail=$first;

    while($tail->next!=$first){

    $tail=$tail->next;

    }

    //考虑是从第几个人开始数数

    for($i=0;$i<$k-1;$i++){

    $tail=$tail->next;

    $first=$first->next;

    }

    //当退出while时,我们的$tail就指向了最后这个小孩

    //让$first和$tail向后移动.

    //移动一次,相当于数2下.

    //移动2次,相当于数了3下,因为自己数的时候是不需要动的.

    while($tail!=$first){ //当$tail==$first则说明只有最后一个人了.

    for($i=0;$i<$m-1;$i++){

    $tail=$tail->next;

    $first=$first->next;

    }

    echo '<br/>出圈额人的编号是'.$first->no;

    //把$first指向的节点小孩删除环形链表

    $first=$first->next;

    $tail->next=$first;

    }

    echo '<br/>最后留在圈圈的人的编号是'.$tail->no;

    }

    addChild($first,$n);

    showChild($first);//死悄悄

    //真正的来玩游戏.

    countChild($first,$m,$k);

    ?>

    </html>

    我给你一个字符串

    “4*8-(9-8)/2+4*67” =>必须学会使用栈来搞定.

    传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季  http://php.itcast.cn

    u 堆栈-最神奇的数据结构

    什么是堆栈:

    堆栈使用的地方:

    1.子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。

    2.处理递归调用:和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。

    3.表达式的转换与求值。//综合的计算器

    4.二叉树的遍历。//前序遍历,后序遍历,中序遍历

    5.图形的深度优先(depth一first)搜索法。//搜索算法

    u 我们来一个快速入门案例,来初步的了解栈的使用

    //一般说,现在的编程语句都提供栈的一些基本操作,比如:入栈, 出栈都有,我们今天自己来实现 入栈, 出栈操作.

    在php 的数组就提供了 入栈 array_push , 出栈 array_pop

    <?php

    $stack = array("orange", "banana");

    array_push($stack, "apple", "葡萄");

    echo "<pre>";

    print_r($stack);

    echo "</pre>";

    //出栈[把栈顶的数据,取出来.]

    $val=array_pop($stack);

    echo '<br/>栈顶='.$val;

    $val=array_pop($stack);

    echo '<br/>栈顶='.$val;

    echo "<pre>";

    print_r($stack);

    echo "</pre>";

    ?>

    现在,我们自己使用数组来实现,出栈和入栈的操作.

    最后的代码:

    <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];

    }

    }

    }

    $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>

    总结:首先使用环形链表,解决约瑟夫问题,然后我们分析了 在PHP 对象传递的原理,后面我们自己是使用数据模拟一个站的操做 =>目标使用我们自己的栈,我完成 一个综合的表达式的计算 .

    简单回顾: 昨天讲了 使用环形链表来解决 约瑟夫问题, 然后我们还讲解了 使用数组来模拟一个栈的操作(pop, push ,打印这个栈数据)

    今天的课程.

    传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季  http://php.itcast.cn

    使用堆栈开发一个 高级的计算器

    3+2*6-2  你把结果给我计算出来!

    问一个问题? 有没有一个函数,可以把个字符串当做一个运算字符来执行?

    : 即使你使用 一个函数就可以把这个算出,他的底层一定是堆栈来实现!

    步骤

    1. 界面搞定.
    2. 思路->画图说明
    3. 现在处理一下多位数的运算.
    4. 处理连续是减号的运算符.

    思考: 请大家思考如何给我们的运算字符,带上 ()

    6*8-(90-78)+60-45

    6*{8-[(90-78)+60]-45}

    6*(8-90)

    思考=>思路 我们给( [ { 都设置运算的优先级 来处理不同的运算

    有同学作出,然后发送到 hanshunping@tsinghua.org.cn  java/c/c++/c#/PHP

    u 综合计算器的最后代码

    <html>

    <head>

    <meta http-equiv='content-type' content='text/html;charset=utf-8'/>

    </head>

    <h1>高级计算器</h1>

    <?php

    //$exp=$_GET['exp'];

    //$exp='300+20*6-20';

    $exp='71*2-50*3-3-67*6+80'; //14-15-3=-4

    //定义一个数栈和一个符号栈

    $numsStack=new MyStack();

    $operStack=new MyStack();

    $keepNum='';//专门用于拼接多位数的字符串

    $index=0;//$index就是一个扫描的标记

    while(true){

    //依次取出字符

    $ch=substr($exp,$index,1);

    //判断$ch是不是一个运算符号.

    if($operStack->isOper($ch)==true){

    //是运算符

    /**

    3.如果发现是运算符

    3.1 如果符号栈为空,就直接入符号栈

    3.2. 如何符号栈,不为空,就判断

    如果当前运算符的优先级小于等于符号栈顶的这个运算符的优先级,就计算,并把计算结果入数栈.然后把当前符号入栈

    3.3 如何符号栈,不为空,就判断

    如果当前运算符的优先级大于符号栈顶的这个运算符的优先级,就入栈.

    */

    if($operStack->isEmpty()){

    $operStack->push($ch);

    }else{

    //需要一个函数,来获取运算符的优先级. * / 1  + -0

    // $chPRI=$operStack->PRI($ch);

    // $stackPRI=$operStack->PRI($operStack->getTop());

    while(!$operStack->isEmpty() && $operStack->PRI($ch)<=$operStack->PRI($operStack->getTop())){

    //从数栈依次出栈两个数.

    $num1=$numsStack->pop();

    $num2=$numsStack->pop();

    //再从符号栈取出一个运算符

    $oper=$operStack->pop();

    //这里还需要一个计算的函数

    $res=$operStack->getResult($num1,$num2,$oper);

    //$res入数栈<font size="" color=""></font>

    $numsStack->push($res);

    }

    //把当前这个符号再入符号栈.//???????问题,一会在解决

    $operStack->push($ch);

    //需要一个函数,来获取运算符的优先级. * / 1  + -0

    /* $chPRI=$operStack->PRI($ch);

    $stackPRI=$operStack->PRI($operStack->getTop());

    if($chPRI<=$stackPRI){

    //从数栈依次出栈两个数.

    $num1=$numsStack->pop();

    $num2=$numsStack->pop();

    //再从符号栈取出一个运算符

    $oper=$operStack->pop();

    //这里还需要一个计算的函数

    $res=$operStack->getResult($num1,$num2,$oper);

    //把$res入数栈<font size="" color=""></font>

    $numsStack->push($res);

    //把当前这个符号再入符号栈.//???????问题,一会在解决

    $operStack->push($ch);

    }else{

    $operStack->push($ch);

    }*/

    }

    }else{

    $keepNum.=$ch;

    //先判断是否已经到字符串最后.如果已经到最后,就直接入栈.

    if($index==strlen($exp)-1){

    $numsStack->push($keepNum);

    }else{

    //要判断一下$ch字符的下一个字符是数字还是符号.

    if($operStack->isOper(substr($exp,$index+1,1))){

    $numsStack->push($keepNum);

    $keepNum='';

    }

    }

    }

    $index++;//$index指向下一个字符.

    //判断是否已经扫描完毕

    if($index==strlen($exp)){

    break;

    }

    }

    /*

    4. 当扫描完毕后,就依次弹出数栈和符号栈的数据,并计算,最总留在数栈的值,就是运算结果,只有符号栈不空就一直计算

    */

    while(!$operStack->isEmpty()){

    $num1=$numsStack->pop();

    $num2=$numsStack->pop();

    $oper=$operStack->pop();

    $res=$operStack->getResult($num1,$num2,$oper);

    $numsStack->push($res);

    }

    //当退出while后,在数栈一定有一个数,这个数就是最后结果

    echo $exp.'='.$numsStack->getTop();

    //这是我们昨天写的一个栈.

    class MyStack{

    private $top=-1;//默认是-1,表示该栈是空的

    private $maxSize=5;//$maxSize表示栈最大容量

    private $stack=array();//

    //计算函数

    public function getResult($num1,$num2,$oper){

    $res=0;

    switch($oper){

    case '+':

    $res=$num1+$num2;

    break;

    case '-':

    $res=$num2-$num1;

    break;

    case '*':

    $res=$num1*$num2;

    break;

    case '/':

    $res=$num2/$num1;

    break;

    }

    return $res;

    }

    //返回栈顶的字符,只是取出,但是不出栈

    public function getTop(){

    return $this->stack[$this->top];

    }

    //判断优先级的函数

    public function PRI($ch){

    if($ch=='*'||$ch=='/'){

    return 1;

    }else if($ch=='+'||$ch=='-'){

    return 0;

    }

    }

    //判断栈是否为空

    public function isEmpty(){

    if($this->top==-1){

    return TRUE;

    }else{

    return FALSE;

    }

    }

    //增加一个函数[提示,在我们开发中,根据需要可以灵活的增加你需要的函数]

     //判断是不是一个运算符

     public function isOper($ch){

    if($ch=='-'||$ch=='+'||$ch=='*'||$ch=='/'){

    return TRUE;

    }else{

    return FALSE;

    }

     }

    //入栈的操作

    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];

    }

    }

    }

    ?>

    </html>

    传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季  http://php.itcast.cn

    u 这里我们讲解了双向链表,完成了一个水浒英雄排行榜.

    双向链表可以完成自我删除,效率相对高,而且你明白这双向链表后,为你将来学习 二叉树打下良好基础.

    最后的代码:

    <html>

    <head>

    <meta http-equiv="content-type" content='text/html;charset=utf-8'/>

    </head>

    <h1>双向链表完成英雄排行管理</h1>

    <hr/>

    <a href='#'>查询英雄</a>|

    <a href='#'>添加英雄</a>|

    <a href='#'>删除英雄</a>|

    <a href='#'>修改英雄</a>

    <?php

    //使用PHP的面向对象的方式来完成.

    class Hero{

    public $pre=null;// 表示指向前一个节点的引用

    public $no;

    public $name;

    public $nickname;

    public $next=null;//表示指向后一个节点的引用

    public function __construct($no='',$name='',$nickname=''){

    $this->no=$no;

    $this->name=$name;

    $this->nickname=$nickname;

    }

    //添加hero,这里我们会构建一个双向链表

    //添加英雄,把添加时是空链表和不是空链表的情况,合并到一起

    public static function addHero($head,$hero){

    $cur=$head;

    //isExist假设不存在

    $isExist=false;

    //如果是空链表就直接加入.

    //给找到一个合适的位置.

    while($cur->next!=null){

    if($cur->next->no>$hero->no){

    //找到位置

    break;

    }else if($cur->next->no==$hero->no){

    $isExist=TRUE;

    echo '<br/>不能抢位置. '.$hero->no.'有人了';

    }

    //继续判断

    $cur=$cur->next;

    }

    //说明还没有这个排名,可以添加,并可以和上面的合并

    if(!$isExist){

    //比如你添加的人就在最后.

    if($cur->next!=null){

    $hero->next=$cur->next;

    }

    $hero->pre=$cur;

    if($cur->next!=null){

    $cur->next->pre=$hero;

    }

    $cur->next=$hero;

    }

    }

    //删除某位英雄

    public static function delHero($head,$herono){

    //我们不使用辅助引用

    $cur=$head->next;

    $isFind=false;

    while($cur!=null){

    if($cur->no==$herono){

    //找到.

    $isFind=true;

    break;

    }

    //下找.

    $cur=$cur->next;

    }

    if($isFind){

    //删除

    if($cur->next!=null){

    $cur->next->pre=$cur->pre;

    }

    $cur->pre->next=$cur->next;

    echo '<br/>要删除的英雄编号是'.$cur->no;

    }else{

    echo '<br/>要删除的英雄没有';

    }

    }

    //显示所有英雄

    public static function showHero($head){

    $cur=$head;

    while($cur->next!=null){

    echo '<br/>排名: '.$cur->next->no.' 名字:'.$cur->next->name.' 外号:'.$cur->next->nickname;

    $cur=$cur->next;

    }

    }

    }

    //创建一个头节点

    $head=new Hero();

    $hero=new Hero(1,'宋江','及时雨');

    Hero::addHero($head,$hero);

    $hero=new Hero(2,'卢俊义','玉麒麟');

    Hero::addHero($head,$hero);

    $hero=new Hero(6,'林冲','豹子头');

    Hero::addHero($head,$hero);

    $hero=new Hero(3,'吴用','智多星');

    Hero::addHero($head,$hero);

    $hero=new Hero(4,'公孙胜','入云龙');

    Hero::addHero($head,$hero);

    echo '<br/> 英雄排行';

    Hero::showHero($head);

    echo '<br/> 删除后的英雄排行';

    Hero::delHero($head,1);

    Hero::delHero($head,6);

    Hero::showHero($head);

    ?>

    </html>

    传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季  http://php.itcast.cn

  • 相关阅读:
    xutils3批量上传文件
    超详细Android面试的准备与经历分享 | 百度(offer)
    [网站公告]3月10日23:00-4:00阿里云SLB升级,会有4-8次连接闪断团队
    上周热点回顾(3.2-3.8)团队
    发布新博客皮肤red_autumnal_leaves团队
    上周热点回顾(2.23-3.1)团队
    上周热点回顾(2.16-2.22)团队
    上周热点回顾(2.2-2.8)团队
    如何禁止IE自动生成链接团队
    [云上天气预报-有时有闪电]2月3日23:00-4:00阿里云SLB升级期间网络会闪断团队
  • 原文地址:https://www.cnblogs.com/sengling/p/5514646.html
Copyright © 2020-2023  润新知