ホームページ >バックエンド開発 >PHPチュートリアル >ハン・シュンピン_PHPソフトウェアエンジニアがアルゴリズムで遊ぶオープンクラス(シーズン1) 03_単一リンクリストCRUD操作_水滸伝ヒーローランキングアルゴリズム_学習ノート_ソースコードイラスト_PPT文書構成

ハン・シュンピン_PHPソフトウェアエンジニアがアルゴリズムで遊ぶオープンクラス(シーズン1) 03_単一リンクリストCRUD操作_水滸伝ヒーローランキングアルゴリズム_学習ノート_ソースコードイラスト_PPT文書構成

WBOY
WBOYオリジナル
2016-06-13 13:02:27868ブラウズ

ハン・シュンピン_アルゴリズムで遊ぶPHPプログラマ公開講座(シーズン1) 03_単一リンクリストCRUD操作_水滸伝ヒーローランキングアルゴリズム_学習ノート_ソースコードイラスト_PPT文書整理

Wen Xi Malong :http://blog. csdn.net/wenximalong/


singleLink.php

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
	</head>
	<body>
		<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;
				}
			}
			//创建一个head头,该head只是一个头,不放入数据
			$head=new Hero();

			//创建一个英雄
			$hero=new Hero(1,'宋江','及时雨');

			//链接
			$head->next=$hero;

			$hero2=new Hero(2,'卢俊义','玉麒麟');
			//链接
			//现在使用的是比较二的方法,马上改进,这样是为了方便理解
			$hero->next=$hero2;

			//单链表的遍历,必须要从head头节点开始找
			//是从head开始遍历的,$head头的值千万不能变,变化后就不能遍历我们的单链表了
			function showHeros($head){
				//遍历[必须要知道什么时候,到了链表的最后]
				//这里为了不去改变$head的指向,我们可以使用一个临时的变量
				$cur=$head;
				while($cur->next!=null){
					//第一个节点为头结点,所以用$cur->next指向下一个节点,头结点里什么都没有是空的
					echo'<br/>英雄的编号是'.$cur->next->no.'名字'.$cur->next->name.'外号='.$cur->next->nickname;
					//如果只写到这里,就会是死循环了
					//所有要让$cul移动
					$cur=$cur->next;
				}
			}

			echo'<br/>***********当前的英雄排行情况是**************';
			showHeros($head);


		?>
	</body>
</html>
上記のコードでは、ヒーローを追加するときに比較的愚かな方法が使用されています。今度は、より良い方法を使用してヒーローを追加します。
1.
をリンクリストの末尾に直接追加します
シングルリンク2.php

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
	</head>
	<body>
		<h1>单向链表完成英雄排行管理</h1>
		<hr/>
		<a href="#">查询英雄</a>
		<a href="#">添加英雄</a>
		<a href="#">删除英雄</a>
		<a href="#">修改英雄</a>
		
		<?php
			//定义英雄类
			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;
				}
			}
			//创建一个head头,该head只是一个头,不放入数据
			$head=new Hero();

			//写一个函数,专门用于添加英雄
			function addHero($head,$hero){
				//1.直接在链表最后加
				//要找到链表的最后,千万不能动$head;
				$cur=$head;
				while($cur->next!=null){
					$cur=$cur->next;
				}
				//当退出while循环的时候,此时$cur就是链表的最后
				//加入hero
				$cur->next=$hero;

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

			//单链表的遍历,必须要从head头节点开始找
			//是从head开始遍历的,$head头的值千万不能变,变化后就不能遍历我们的单链表了
			function showHeros($head){
				//遍历[必须要知道什么时候,到了链表的最后]
				//这里为了不去改变$head的指向,我们可以使用一个临时的变量
				$cur=$head;
				while($cur->next!=null){
					//第一个节点为头结点,所以用$cur->next指向下一个节点,头结点里什么都没有是空的
					echo'<br/>英雄的编号是'.$cur->next->no.'名字'.$cur->next->name.'外号='.$cur->next->nickname;
					//如果只写到这里,就会是死循环了
					//所有要让$cul移动
					$cur=$cur->next;
				}
			}

			//添加
			$hero=new Hero(1,'宋江','及时雨');
			addHero($head,$hero);
			$hero=new Hero(2,'卢俊义','玉麒麟');
			addHero($head,$hero);
			$hero=new Hero(6,'林冲','豹子头');
			addHero($head,$hero);
			$hero=new Hero(3,'吴用','智多星');
			addHero($head,$hero);
			//在输出的时候,林冲就排在了吴用的前面了,而林冲是6号,应当排在吴用的后面,这就是直接在链表最后添加的弊端。

			echo'<br/>***********当前的英雄排行情况是**************';
			showHeros($head);
		?>
	</body>
</html>



2. ヒーローのランキングに従って参加します (ここではリンクリストの順序を保証したいと考えています)
将来仕事をするときに、誰かが大量の文字列を渡して、その文字列の特定の属性に従ってそれらを並べ替えるように依頼されると、その並べ替えはメモリ内で行われるかもしれません。
それらを順番に追加するにはどうすればよいですか?

★必ず最初にアイデアについて話し、それからコードを書いてください。 分析チャート

画像は大きいため、新しいウィンドウで画像を開いて全体を表示してください


非常に極端な例を考えてみましょう。
(1) 最初に文字 1 を追加します。最初の cur はヘッド ノードを指します。cur->next は空です。文字 1 をヘッド ノードの直後に追加します。
(2) 文字番号 2 を追加します。最初の cur はヘッド ノードを指します。cur->next は文字ノード 1 を指します。cur->next->no は 1、$hero->no は次のとおりです。比較のために2と比較すると、1が2より大きくないことがわかったので、curは1段下に進む。このとき、curは文字ノード1番を指し、cur->next->noであるか否かを判定する。 2 より大きいため、現時点では cur->next は空であり、文字ノード No. 1 の後ろに文字 No. 2 を追加することしかできません。
(3) 文字番号 6 を追加します。最初の cur はヘッド ノードを指し、cur->next は今度は文字ノード 1 を指します。cur->next->no は 1、$hero->next は比較のために 6 を計算すると、1 は 6 より大きくないことが判明したため、cur は 1 番目の文字ノードを指し、cur->next->no が 2 と判断されます。 $hero->no を 6 として比較したところ、2 が 6 より大きくないことが判明したため、cur は 1 つ下に進み、文字ノード 2 を指します。 >next->no は 6 より大きいです。この時点では cur->next は空であり、文字ノード 2 の後に文字 6 を追加することしかできません。
(4) 文字番号 3 を追加します。最初の cur はヘッド ノードを指し、cur->next は今度は文字ノード 1 を指します。cur->next->no は 1、$hero->next は比較のために 3 を計算すると、1 は 3 より大きくないことがわかり、cur は 1 つ下に進みます。このとき、cur は 1 番目の文字ノードを指し、cur->next->no は 2 と判断されます。 $hero->no を 3 として比較したところ、2 が 3 より大きくないことが判明したため、cur は 1 つ下に進みます。このとき、cur は 2 番目の文字ノードを指し、cur-> と判断されます。 ;next->no as 6 and $hero->no as 3. 比較した結果、6 が 3 より大きいことがわかり、その位置が 3 番から 3 番までの文字を追加する方法を見つけようとしました。手術。
シングルリンク3.php

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
	</head>
	<body>
		<h1>单向链表完成英雄排行管理</h1>
		<hr/>
		<a href="#">查询英雄</a>
		<a href="#">添加英雄</a>
		<a href="#">删除英雄</a>
		<a href="#">修改英雄</a>
		
		<?php
			//定义英雄类
			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;
				}
			}
			//创建一个head头,该head只是一个头,不放入数据
			$head=new Hero();

			//写一个函数,专门用于添加英雄
			function addHero($head,$hero){
				//1.直接在链表最后加
				//要找到链表的最后,千万不能动$head;
				$cur=$head;
				//2.按照英雄的排行加入(这里我希望能够保证链表的顺序)
				//思路:一定要先谈思路,再写代码
				while($cur->next!=null){
					if($cur->next->no>=$hero->no){
						//找到位置了
						break; //一旦break,就跳出了while循环
					}
					//继续
					$cur=$cur->next;
				}
				//当退出while循环的时候,位置找到
				//加入

				//让hero加入
				$hero->next=$cur->next;
				$cur->next=$hero;
			}

			//单链表的遍历,必须要从head头节点开始找
			//是从head开始遍历的,$head头的值千万不能变,变化后就不能遍历我们的单链表了
			function showHeros($head){
				//遍历[必须要知道什么时候,到了链表的最后]
				//这里为了不去改变$head的指向,我们可以使用一个临时的变量
				$cur=$head;
				while($cur->next!=null){
					//第一个节点为头结点,所以用$cur->next指向下一个节点,头结点里什么都没有是空的
					echo'<br/>英雄的编号是'.$cur->next->no.'名字'.$cur->next->name.'外号='.$cur->next->nickname;
					//如果只写到这里,就会是死循环了
					//所有要让$cul移动
					$cur=$cur->next;
				}
			}

			//添加
			$hero=new Hero(1,'宋江','及时雨');
			addHero($head,$hero);
			$hero=new Hero(2,'卢俊义','玉麒麟');
			addHero($head,$hero);
			$hero=new Hero(6,'林冲','豹子头');
			addHero($head,$hero);
			$hero=new Hero(3,'吴用','智多星');
			addHero($head,$hero);
			//在输出的时候,林冲就排在了吴用的前面了,而林冲是6号,应当排在吴用的后面,这就是直接在链表最后添加的弊端。

			echo'<br/>***********当前的英雄排行情况是**************';
			showHeros($head);
		?>
	</body>
</html>

実行プロセス分析図

画像は大きいため、新しいウィンドウで画像を開いて全体を表示してください


上図のように、 でキャラクタ 3 番を追加すると、cur はキャラクタ ノード 2 番を指し、cur->next はキャラクタ ノード 6 番のアドレス 0x1234 を指します。このとき、キャラクタNo.3のアドレスは0x345になります。 $hero->next=$cur->next; を実行します。つまり、青い点線①のように、キャラクタ番号 3 のノードのネクストがキャラクタ番号 6 のノード アドレス 0x1234 を指すようにします。図の場合; then $cur->next= $hero; つまり、文字ノード 2 のネクストをアドレス 0x1234 から文字ノード 3 のアドレス 0x345 に変更します。図の③青い点線は、元の②実線が切れています。
このようにして、文字 No.2 の後ろに文字 No.3 が挿入されます。
ただ見ているだけでは学べません。自分でコードを入力し、絵を描き、分析して理解を深めてください。

追加された改善点:
同じランキングのヒーローをリンク リストに追加できないようにします。

singleLink3.php の while ループ コードを次のように変更します:
シングルリンク4.php

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
	</head>
	<body>
		<h1>单向链表完成英雄排行管理</h1>
		<hr/>
		<a href="#">查询英雄</a>
		<a href="#">添加英雄</a>
		<a href="#">删除英雄</a>
		<a href="#">修改英雄</a>
		
		<?php
			//定义英雄类
			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;
				}
			}
			//创建一个head头,该head只是一个头,不放入数据
			$head=new Hero();

			//写一个函数,专门用于添加英雄
			function addHero($head,$hero){
				//1.直接在链表最后加
				//要找到链表的最后,千万不能动$head;
				$cur=$head;
				//2.按照英雄的排行加入(这里我希望能够保证链表的顺序)
				//思路:一定要先谈思路,再写代码
				$flag=false; //表示没有重复的编号
				while($cur->next!=null){
					if($cur->next->no>$hero->no){
						//找到位置了
						break;
					}else if($cur->next->no==$hero->no){
						$flag=true; //如果进入此处,就说明有重复的了,置为true
						echo'<br/>不能抢位置,'.$hero->no.'位置已经有人了';
					}
					//继续
					$cur=$cur->next;
				}
				//当退出while循环的时候,位置找到
				//加入

				//让hero加入
				if($flag==false){ //只有当$flag为false的时候,说明没有遇到重复的,才会执行插入。如果不加$flag标志位,虽然上面的else if判断了,遇到重复的,但是仍然会插入。
					$hero->next=$cur->next;
					$cur->next=$hero;
				}
			}

			//单链表的遍历,必须要从head头节点开始找
			//是从head开始遍历的,$head头的值千万不能变,变化后就不能遍历我们的单链表了
			function showHeros($head){
				//遍历[必须要知道什么时候,到了链表的最后]
				//这里为了不去改变$head的指向,我们可以使用一个临时的变量
				$cur=$head;
				while($cur->next!=null){
					//第一个节点为头结点,所以用$cur->next指向下一个节点,头结点里什么都没有是空的
					echo'<br/>英雄的编号是'.$cur->next->no.'名字'.$cur->next->name.'外号='.$cur->next->nickname;
					//如果只写到这里,就会是死循环了
					//所有要让$cul移动
					$cur=$cur->next;
				}
			}

			//添加
			$hero=new Hero(1,'宋江','及时雨');
			addHero($head,$hero);
			$hero=new Hero(2,'卢俊义','玉麒麟');
			addHero($head,$hero);
			$hero=new Hero(6,'林冲','豹子头');
			addHero($head,$hero);
			$hero=new Hero(3,'吴用','智多星');
			addHero($head,$hero);
			$hero=new Hero(1,'宋江','及时雨');
			addHero($head,$hero);
			$hero=new Hero(2,'卢俊义','玉麒麟');
			addHero($head,$hero);
			//在输出的时候,林冲就排在了吴用的前面了,而林冲是6号,应当排在吴用的后面,这就是直接在链表最后添加的弊端。

			echo'<br/>***********当前的英雄排行情况是**************';
			showHeros($head);
		?>
	</body>
</html>
上記は追加機能です。
=============
削除機能を追加します:

分析チャート

画像は大きいため、新しいウィンドウで画像を開いて全体を表示してください


现在有3个人物节点,要把3号人物节点删除。
(1)首先有一个变量cur指向了head节点,即$cur=$head;$cur->next!=null成立,进入while循环,进行if判断,$cur->next->no为1,则和$herono为3不相等,cur向下走一步。
(2)此时cur指向了1号人物节点,$cur->next!=null成立,进入while循环,进行if判断,
$cur->next->no为3,则和$herono为3相等,找到位置了就break跳出了while循环。就要把这个3号人物节点拿掉,应该怎么拿呢?假设3号人物节点地址为0x123,7号人物节点地址为0x456,现在就是要把1号人物节点的next值改为0x456,这样3号人物节点就不在此单链表中了。有人会有疑惑:3号人物节点不是也有next值,指向0x456吗即指向7号人物节点的,不用担心,此时3号人物节点已经是垃圾对象了,因为在php、java和c#中都有规定,如果一个对象没有任何一个引用指向它,它就是垃圾了,这一点一定要清楚,垃圾回收机制就会把3号人物节点回收了,这就是拿掉3号人物节点的思路。
删除代码

$cur->next=$cur->next->next;
注意:当你刚好删除的末尾会不会有问题呢?
删除最后一个节点,即要删除7号人物,那么cur就定位到了3号人物节点,此时$cur->next->next就是 7号人物节点的next属性值,7号人物节点是最后一个节点,它的next属性值为null,那么$cur->next=$cur->next->next;就是把3号人物节点的next属性值置为null,那么此时3号人物节点就是最后一个节点了就是末尾了。

singleLink5.php

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
	</head>
	<body>
		<h1>单向链表完成英雄排行管理</h1>
		<hr/>
		<a href="#">查询英雄</a>
		<a href="#">添加英雄</a>
		<a href="#">删除英雄</a>
		<a href="#">修改英雄</a>
		
		<?php
			//定义英雄类
			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;
				}
			}
			//创建一个head头,该head只是一个头,不放入数据
			$head=new Hero();

			//写一个函数,专门用于添加英雄
			function addHero($head,$hero){
				//1.直接在链表最后加
				//要找到链表的最后,千万不能动$head;
				$cur=$head;
				//2.按照英雄的排行加入(这里我希望能够保证链表的顺序)
				//思路:一定要先谈思路,再写代码
				$flag=false; //表示没有重复的编号
				while($cur->next!=null){
					if($cur->next->no>$hero->no){
						//找到位置了
						break;
					}else if($cur->next->no==$hero->no){
						$flag=true; //如果进入此处,就说明有重复的了,置为true
						echo'<br/>不能抢位置,'.$hero->no.'位置已经有人了';
					}
					//继续
					$cur=$cur->next;
				}
				//当退出while循环的时候,位置找到
				//加入

				//让hero加入
				if($flag==false){ //只有当$flag为false的时候,说明没有遇到重复的,才会执行插入。如果不加$flag标志位,虽然上面的else if判断了,遇到重复的,但是仍然会插入。
					$hero->next=$cur->next;
					$cur->next=$hero;
				}
			}

			//单链表的遍历,必须要从head头节点开始找
			//是从head开始遍历的,$head头的值千万不能变,变化后就不能遍历我们的单链表了
			function showHeros($head){
				//遍历[必须要知道什么时候,到了链表的最后]
				//这里为了不去改变$head的指向,我们可以使用一个临时的变量
				$cur=$head;
				while($cur->next!=null){
					//第一个节点为头结点,所以用$cur->next指向下一个节点,头结点里什么都没有是空的
					echo'<br/>英雄的编号是'.$cur->next->no.'名字'.$cur->next->name.'外号='.$cur->next->nickname;
					//如果只写到这里,就会是死循环了
					//所有要让$cul移动
					$cur=$cur->next;
				}
			}

			//从链表中删除某个英雄
			function delHero($head,$herono){
				//首先要找到这个英雄在哪里
				$cur=$head; //让$cur指向$head;
				$flag=false; //标志位,假设没有找到
				while($cur->next!=null){
					if($cur->next->no==$herono){
						$flag=true; //进入if语句就说明找到了,置为true
						//找到 $cur的下一个节点就是应该被删除的节点。
						break;
					}
					$cur=$cur->next;
				}
				if($flag){ //如果flag为真,就删除
					//删除
					$cur->next=$cur->next->next;
				}else{
					echo'<br/>没有你要删除的英雄的编号'.$herono;
				}
			}

			//添加
			$hero=new Hero(1,'宋江','及时雨');
			addHero($head,$hero);
			$hero=new Hero(2,'卢俊义','玉麒麟');
			addHero($head,$hero);
			$hero=new Hero(6,'林冲','豹子头');
			addHero($head,$hero);
			$hero=new Hero(3,'吴用','智多星');
			addHero($head,$hero);
			$hero=new Hero(1,'宋江','及时雨');
			addHero($head,$hero);
			$hero=new Hero(2,'卢俊义','玉麒麟');
			addHero($head,$hero);
			//在输出的时候,林冲就排在了吴用的前面了,而林冲是6号,应当排在吴用的后面,这就是直接在链表最后添加的弊端。

			echo'<br/>***********当前的英雄排行情况是**************';
			showHeros($head);
			echo'<br/>***********删除后的英雄排行情况是**************';
			delHero($head,1);
			delHero($head,21); //删除一个不存在的
			showHeros($head);
		?>
	</body>
</html>
========
继续添加修改功能:

singleLink6.php

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
	</head>
	<body>
		<h1>单向链表完成英雄排行管理</h1>
		<hr/>
		<a href="#">查询英雄</a>
		<a href="#">添加英雄</a>
		<a href="#">删除英雄</a>
		<a href="#">修改英雄</a>
		
		<?php
			//定义英雄类
			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;
				}
			}
			//创建一个head头,该head只是一个头,不放入数据
			$head=new Hero();

			//写一个函数,专门用于添加英雄
			function addHero($head,$hero){
				//1.直接在链表最后加
				//要找到链表的最后,千万不能动$head;
				$cur=$head;
				//2.按照英雄的排行加入(这里我希望能够保证链表的顺序)
				//思路:一定要先谈思路,再写代码
				$flag=false; //表示没有重复的编号
				while($cur->next!=null){
					if($cur->next->no>$hero->no){
						//找到位置了
						break;
					}else if($cur->next->no==$hero->no){
						$flag=true; //如果进入此处,就说明有重复的了,置为true
						echo'<br/>不能抢位置,'.$hero->no.'位置已经有人了';
					}
					//继续
					$cur=$cur->next;
				}
				//当退出while循环的时候,位置找到
				//加入

				//让hero加入
				if($flag==false){ //只有当$flag为false的时候,说明没有遇到重复的,才会执行插入。如果不加$flag标志位,虽然上面的else if判断了,遇到重复的,但是仍然会插入。
					$hero->next=$cur->next;
					$cur->next=$hero;
				}
			}

			//单链表的遍历,必须要从head头节点开始找
			//是从head开始遍历的,$head头的值千万不能变,变化后就不能遍历我们的单链表了
			function showHeros($head){
				//遍历[必须要知道什么时候,到了链表的最后]
				//这里为了不去改变$head的指向,我们可以使用一个临时的变量
				$cur=$head;
				while($cur->next!=null){
					//第一个节点为头结点,所以用$cur->next指向下一个节点,头结点里什么都没有是空的
					echo'<br/>英雄的编号是'.$cur->next->no.'名字'.$cur->next->name.'外号='.$cur->next->nickname;
					//如果只写到这里,就会是死循环了
					//所有要让$cul移动
					$cur=$cur->next;
				}
			}

			//从链表中删除某个英雄
			function delHero($head,$herono){
				//首先要找到这个英雄在哪里
				$cur=$head; //让$cur指向$head;
				$flag=false; //标志位,假设没有找到
				while($cur->next!=null){
					if($cur->next->no==$herono){
						$flag=true; //进入if语句就说明找到了,置为true
						//找到 $cur的下一个节点就是应该被删除的节点。
						break;
					}
					$cur=$cur->next;
				}
				if($flag){ //如果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;
				}
				//这次不使用flag标志位了
				//当退出while循环后,如果$cur->next==null说明cur到队尾了,也没有找到
				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(6,'林冲','豹子头');
			addHero($head,$hero);
			$hero=new Hero(3,'吴用','智多星');
			addHero($head,$hero);
			$hero=new Hero(1,'宋江','及时雨');
			addHero($head,$hero);
			$hero=new Hero(2,'卢俊义','玉麒麟');
			addHero($head,$hero);
			//在输出的时候,林冲就排在了吴用的前面了,而林冲是6号,应当排在吴用的后面,这就是直接在链表最后添加的弊端。

			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);
		?>
	</body>
</html>
关键是运用,如用环形链表解决丢手帕问题。
为什么没有思想,就是没有算法和数据结构,无从下手。
把这个单链表的案例,自己敲下来,就会发现没有这么难。

使用带head头的双向链表实现―水浒英雄排行榜管理

单向链表的缺点分析:不能自我删除,需要靠辅助节点。
而双向链表,则可以自我删除,同时在二叉树,广义表中都需要使用到一个节点执行两个或者多个节点的运用!


韩顺平_PHP程序员玩转算法公开课_学习笔记_源代码图解_PPT文档整理_目录


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。