php数字截取2位小树,数据结构-PHP 二分搜索树的层序遍历(队列实现)
?前面文章介紹了二分搜索樹的?前序遍歷、中序遍歷、后續(xù)遍歷,這篇文章主要介紹一下如何使用?隊(duì)列?實(shí)現(xiàn)二分搜索樹的?層序遍歷。
1.隊(duì)列
1.1 隊(duì)列的特點(diǎn)隊(duì)列(Queue)?是一種線性結(jié)構(gòu)。
只能從一端?tail(隊(duì)尾)?添加元素,從另外一端?front(隊(duì)首)?取出元素。
是一種 First In First Out(FIFO),即 先進(jìn)先出 的結(jié)構(gòu)。
1.2 隊(duì)列的圖示
1.3 鏈表
這是封裝好的一個(gè)鏈表類,能實(shí)現(xiàn)鏈表的基本功能:<?php
/**
* 鏈表的實(shí)現(xiàn)
* Class LinkedList
*/
class LinkedList
{
private $dummyHead;
private $size;
/**
* 初始化鏈表 null->null
* LinkedList constructor.
*/
public function __construct() {
$this->dummyHead = new Node(null, null);
$this->size = 0;
}
/**
* 獲取鏈表大小
* @return int
*/
public function getSize(): int {
return $this->size;
}
/**
* 判斷鏈表是否為空
* @return bool
*/
public function isEmpty(): bool {
return $this->size == 0;
}
/**
* 在鏈表的第 index 位置添加元素
* @param int $index
* @param $e
*/
public function add(int $index, $e): void {
if ($index < 0 || $index > $this->size) {
echo "索引范圍錯(cuò)誤";
exit;
}
$prve = $this->dummyHead;
for ($i = 0; $i < $index; $i++) {
$prve = $prve->next;
}
//將上插入位置的上一個(gè)位置的 next 節(jié)點(diǎn)指向插入節(jié)點(diǎn),插入節(jié)點(diǎn)的 next 節(jié)點(diǎn)信息指向原上節(jié)點(diǎn)的 next 節(jié)點(diǎn)
$prve->next = new Node($e, $prve->next);
$this->size++;
}
/**
* 向鏈表開頭添加元素
* @param $e
*/
public function addFirst($e): void {
$this->add(0, $e);
}
/**
* 向鏈表末尾添加元素
* @param $e
*/
public function addLast($e): void {
$this->add($this->size, $e);
}
/**
* 獲取鏈表第 index 位置元素
* @param $index
*/
public function get($index) {
if ($index < 0 || $index > $this->size) {
echo "索引范圍錯(cuò)誤";
exit;
}
$node = $this->dummyHead;
for ($i = 0; $i < $index + 1; $i++) {
$node = $node->next;
}
return $node->e;
}
/**
* 獲取鏈表第一個(gè)元素
* @return mixed
*/
public function getFirst() {
return $this->get(0);
}
/**
* 獲取鏈表最后一個(gè)元素
* @return mixed
*/
public function getLast() {
return $this->get($this->size - 1);
}
/**
* 修改鏈表中第 index 位置元素值
* @param $index
* @param $e
*/
public function update($index, $e) {
if ($index < 0 || $index > $this->size) {
echo "索引范圍錯(cuò)誤";
exit;
}
$node = $this->dummyHead;
for ($i = 0; $i < $index + 1; $i++) {
$node = $node->next;
}
$node->e = $e;
}
/**
* 判斷鏈表中是否存在某個(gè)元素
* @param $e
* @return bool
*/
public function contains($e): bool {
for ($node = $this->dummyHead->next; $node != null; $node = $node->next) {
if ($node->e == $e) {
return true;
}
}
return true;
}
/**
* 刪除鏈表中第 index 位置元素
* @param $index
*/
public function remove($index) {
if ($index < 0 || $index > $this->size) {
echo "索引范圍錯(cuò)誤";
exit;
}
if ($this->size == 0) {
echo "鏈表已經(jīng)是空";
exit;
}
$prve = $this->dummyHead;
for ($i = 0; $i < $index; $i++) {
$prve = $prve->next;
}
$node = $prve->next;
$prve->next = $node->next;
$this->size--;
return $node->e;
}
/**
* 刪除鏈表頭元素
*/
public function removeFirst() {
return $this->remove(0);
}
/**
* 刪除鏈表末尾元素
*/
public function removeLast() {
return $this->remove($this->size - 1);
}
/**
* 鏈表元素轉(zhuǎn)化為字符串顯示
* @return string
*/
public function toString(): string {
$str = "";
for ($node = $this->dummyHead->next; $node != null; $node = $node->next) {
$str .= $node->e . "->";
}
return $str . "null";
}
}
class Node
{
public $e;//節(jié)點(diǎn)元素
public $next; //下個(gè)節(jié)點(diǎn)信息
/**
* 構(gòu)造函數(shù) 設(shè)置節(jié)點(diǎn)信息
* Node constructor.
* @param $e
* @param $next
*/
public function __construct($e, $next) {
$this->e = $e;
$this->next = $next;
}
}
1.4 隊(duì)列
這是通過帶?尾指針?鏈表實(shí)現(xiàn)的?隊(duì)列?類,它里面有?入隊(duì)(enqueue)?方法和?出隊(duì)(dequque)?方法 :<?php
/**
* 帶有尾指針的鏈表
* Class LinkedListTail
*/
class QueueByLinkedList
{
private $head; //鏈表頭部
private $tail; //鏈表尾部
private $size; //鏈表大小
/**
* 構(gòu)造函數(shù) 初始化鏈表
* QueueByLinkedList constructor.
*/
public function __construct() {
$this->head = null;
$this->tail = null;
$this->size = 0;
}
/**
* 入隊(duì)操作
* @param $e
*/
public function enqueue($e): void {
if ($this->tail == null) {
$this->tail = $this->head = new Node($e, null);
} else {
$node = new Node($e, null);
$this->tail->next = $node;
$this->tail = $node;
}
$this->size++;
}
/**
* 出隊(duì)操作
* @return mixed
*/
public function dequeue() {
if ($this->size == 0) {
return "隊(duì)列已經(jīng)是空的";
}
$node = $this->head;
$this->head = $node->next;
$this->size--;
if ($node->next == null) {
$this->tail = null;
}
return $node->e;
}
public function getFront() {
if ($this->size == 0) {
return "隊(duì)列已經(jīng)是空的";
}
return $this->head->e;
}
public function getSize() {
return $this->size;
}
/**
* 判斷隊(duì)列是否為空
* @return bool
*/
public function isEmpty(): bool {
return $this->size == 0;
}
public function toString() {
$str = "";
for ($node = $this->head; $node != null; $node = $node->next) {
$str .= $node->e . "->";
}
$str .= "null";
return $str;
}
}
class Node
{
public $e;//節(jié)點(diǎn)元素
public $next; //下個(gè)節(jié)點(diǎn)信息
/**
* 構(gòu)造函數(shù) 設(shè)置節(jié)點(diǎn)信息
* Node constructor.
* @param $e
* @param $next
*/
public function __construct($e, $next) {
$this->e = $e;
$this->next = $next;
}
}
2.二分搜索樹層序遍歷
2.1 節(jié)點(diǎn)定義2.3 PHP 代碼定義節(jié)點(diǎn)
class Node
{
public $e;
public $left = null;
public $right = null;
/**
* 構(gòu)造函數(shù) 初始化節(jié)點(diǎn)數(shù)據(jù)
* Node constructor.
* @param $e
*/
public function __construct($e) {
$this->e = $e;
}
}
2.2 原理說明
利用?隊(duì)列?的特點(diǎn),從根節(jié)點(diǎn)開始,先把根節(jié)點(diǎn)入隊(duì),然后出隊(duì)的時(shí)候需要判斷出隊(duì)元素是否為空,若不為空,先處理當(dāng)前節(jié)點(diǎn),然后先把?左兒子節(jié)點(diǎn)入隊(duì),然后?右兒子?節(jié)點(diǎn)入隊(duì),以此類推直到?jīng)]有兒子節(jié)點(diǎn)的時(shí)候就可以繼續(xù)?出隊(duì)?下一個(gè)元素了,直到?隊(duì)列?為空表示遍歷完畢,通過這種?隊(duì)列?的思想可以達(dá)到?層序遍歷二分搜索樹?的目的。Tips:若不為空的節(jié)點(diǎn)沒有兒子節(jié)點(diǎn),這里實(shí)際處理它的兒子節(jié)點(diǎn)也會入棧?null。
2.3 實(shí)現(xiàn)原理圖示
2.4 二分搜索樹層序遍歷
下面展示的都是部分代碼,需要結(jié)合之前的,層序遍歷?是按照節(jié)點(diǎn)深度一層一層的遍歷:/**
* 層序遍歷實(shí)現(xiàn)
*/
public function tierTraversalByLinkedList() {
$queue = new QueueByLinkedList();
//將根節(jié)點(diǎn)入隊(duì)
$queue->enqueue($this->root);
//循環(huán)依次出隊(duì)
$node = $queue->dequeue();
do {
if ($node != null) { //若出棧的當(dāng)前節(jié)點(diǎn)不是空
echo $node->e . "
"; //然后打印當(dāng)前節(jié)點(diǎn)信息
$queue->enqueue($node->left);//左兒子入隊(duì)
$queue->enqueue($node->right);//右兒子入隊(duì)
} else { //若是空
echo "null
";
}
//繼續(xù)出隊(duì)
$node = $queue->dequeue();
} while (!$queue->isEmpty());
}Tips:若不為空的節(jié)點(diǎn)沒有兒子節(jié)點(diǎn),這里實(shí)際處理它的兒子節(jié)點(diǎn)也會入棧?null。
下面是打印結(jié)果:<?php
require 'BinarySearchTree.php';
$binarySearchTree = new BinarySearchTree();
$binarySearchTree->add(45);
$binarySearchTree->add(30);
$binarySearchTree->add(55);
$binarySearchTree->add(25);
$binarySearchTree->add(35);
$binarySearchTree->add(50);
$binarySearchTree->add(65);
$binarySearchTree->add(15);
$binarySearchTree->add(27);
$binarySearchTree->add(31);
$binarySearchTree->add(48);
$binarySearchTree->add(60);
$binarySearchTree->add(68);
//下面是預(yù)期想要的結(jié)果
/**
* 45
* /
* 30 55
* / /
* 25 35 50 65
* / / / /
* 15 27 31 48 60 68
*
*/
$binarySearchTree->tierTraversalByLinkedList();
/**
打印輸出
45
30
55
25
35
50
65
15
27
31
null
48
null
60
68
null
null
null
null
null
null
null
null
null
null
null
*/Tips:可以看到打印輸出結(jié)果和預(yù)期一致。
掃碼關(guān)注愛因詩賢
總結(jié)
以上是生活随笔為你收集整理的php数字截取2位小树,数据结构-PHP 二分搜索树的层序遍历(队列实现)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电影(《龙之谷,破晓奇兵》,《龙之谷,精
- 下一篇: 急求助!淘宝申请退货退款申请不了是怎么回