用戶二叉樹排序需求
用戶注冊,輸入以下注冊信息:
- 電子郵箱
- 密碼
- 確認(rèn)密碼
- 推薦人ID(此ID可以在數(shù)據(jù)庫中手動增加一個)
每注冊進(jìn)一個新用戶,該用戶就進(jìn)入到排序中
排序規(guī)則
下列是圖解:
假設(shè)A是根節(jié)點(diǎn)(A就是手動添加的第一位用戶)
有一個新用戶注冊進(jìn)來(假設(shè)新用戶為B),推薦人ID填寫的是A的ID,則排序如下:
A
/
B
又有一位C用戶注冊,推薦人ID填寫的是B的ID,則:
A
/
B
/
C
有一位D用戶注冊,推薦人ID填寫的是A的ID,則:
A
/ \
B D
/
C
有一位E用戶注冊,推薦人ID填寫的是B的ID,則
A
/ \
B D
/ \
C E
有一位F用戶注冊,推薦人ID填寫的是A的ID,則
A
/ \
B D
/ \ /
C E F
有一位G用戶注冊,推薦人ID填寫的是E的ID,則
A
/ \
B D
/ \ /
C E F
/
G
有一位H用戶注冊,推薦人ID填寫的是B的ID,則
H的推薦人是B,所以,H必定是在B的下面,然后按照從左到右的方式查找,C和E占了上面的兩個位置,所以到下一排查找,找到空位,則插入H,以下都是這種規(guī)律
A
/ \
B D
/ \ /
C E F
/ /
H G
有一位I用戶,和J用戶又陸續(xù)注冊進(jìn)來,填寫的都是C的ID,則
A
/ \
B D
/ \ /
C E F
/ \ /
H I G
/
J
有一位K用戶,和L用戶又陸續(xù)注冊進(jìn)來,填寫的都是A的ID,則
A
/ \
B D
/ \ / \
C E F K
/ \ / \
H I G L
/
J
有一位M用戶,N用戶和O用戶 又注冊進(jìn)來,填寫的分別是B用戶,C用戶,和L用戶的ID,則:
A
/ \
B D
/ \ / \
C E F K
/ \ / \
H I G L
/ \
J M
A
/ \
B D
/ \ / \
C E F K
/ \ / \
H I G L
/ \ /
J M N
A
/ \
B D
/ \ / \
C E F K
/ \ / \
H I G L
/ \ / /
J M N O
有一位P用戶、Q用戶、R用戶、S用戶又注冊進(jìn)來,填寫的分別是A用戶,B用戶,E用戶,A用戶的ID。則:
A
/ \
B D
/ \ / \
C E F K
/ \ / \ /
H I G L P
/ \ / /
J M N O
A
/ \
B D
/ \ / \
C E F K
/ \ / \ /
H I G L P
/ \ / \ /
J M N Q O
A
/ \
B D
/ \ / \
C E F K
/ \ / \ /
H I G L P
/ \ / \ / /
J M N Q R O
A
/ \
B D
/ \ / \
C E F K
/ \ / \ / \
H I G L P S
/ \ / \ / /
J M N Q R O
人生最曼妙的風(fēng)景,竟是內(nèi)心的淡定與從容!
不談為何要實現(xiàn)這樣一個奇怪的需求。
就簡單實現(xiàn)這個功能來講,可以根據(jù)數(shù)據(jù)結(jié)構(gòu)中二叉樹的順序存儲方式來解決吧。
這里就用PHP中的數(shù)組來模擬二叉樹的順序存儲,數(shù)組中的key相當(dāng)于存儲地址,value相當(dāng)于存儲的數(shù)據(jù)。當(dāng)然key為有類似下面這樣的結(jié)構(gòu):
0
/ \
1 2
也就是父節(jié)點(diǎn)key值記為n,則左子節(jié)點(diǎn)key為2n+1,右子節(jié)點(diǎn)key為2(n+1)。下面簡單用PHP代碼實現(xiàn)下吧(由家里本本沒有PHP運(yùn)行環(huán)境,沒測試代碼的完全正確性@#@):
php
class Tree { private $data = []; public function __construct() {} /** * @param mixed $val * @param int $pid 父節(jié)點(diǎn)在$data中的key值 * @return int 返回插入節(jié)點(diǎn)的對應(yīng)在$data中的key值 */ public function add($val, $pid = 0) { // 若為空樹則插入根節(jié)點(diǎn) if (!count($this->data)) { $this->data[0] = $val; return 0; } // 若左子節(jié)點(diǎn)為空則插入左子節(jié)點(diǎn) if (!isset($this->data[2*$pid+1])) { $this->data[2*$pid+1] = $val; return 2*$pid+1; } // 若右子節(jié)點(diǎn)為空則插入右子節(jié)點(diǎn) if (!isset($this->data[2*$pid+2])) { $this->data[2*pid+2] = val; return 2*pid+2; } // 獲取$data中最后一個節(jié)點(diǎn)的key值 $maxKey = max(array_keys($this->data); // 如果是完全二叉樹的情況(也就是$data中沒有空節(jié)點(diǎn))則在$data最后插入值 if (count($this->data) === $maxKey + 1) { $this->data[$maxKey+1] = $val; return $maxKey + 1; } // 不為完全二叉樹則在$data中最小的空key處插入值 for ($i = 0; $i <= $maxKey; ++$i) { if (!isset($this->data[$i])) { $this->data[$i] = $val; return $i; } } } } // 簡單測試 $tree = new Tree(); $aid = $tree->add('A', 0); $bid = $tree->add('B', $aid); $tree->add('C', $bid);
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號