本文目錄一覽:
如何使用強大的PHP函數對數組進行排序
如果你已經使用了一段時間PHP的話,那麼,你應該已經對它的數組比較熟悉了——這種數據結構允許你在單個變數中存儲多個值,並且可以把它們作為一個集合進行操作。
經常,開發人員發現在PHP中使用這種數據結構對值或者數組元素進行排序非常有用。PHP提供了一些適合多種數組的排序函數,這些函數允許你在數組內部對元素進行排列,也允許用很多不同的方法對它們進行重新排序。在這篇文章中我們將討論該排序中最重要的幾個函數。
簡單排序
首先,讓我們來看看最簡單的情況:將一個數組元素從低到高進行簡單排序,這個函數既可以按數字大小排列也可以按字母順序排列。PHP的sort()函數實現了這個功能,如Listing A所示:
Listing A
?php
 $data = array(5,8,1,7,2);
 sort($data);
 print_r($data);
 ?
輸出結果如下所示:
Array ([0] = 1
[1] = 2
[2] = 5
[3] = 7
[4] = 8
)
也能使用rsort()函數進行排序,它的結果與前面所使用的sort()簡單排序結果相反。Rsort()函數對數組元素進行從高到低的倒排,同樣可以按數字大小排列也可以按字母順序排列。Listing B給我們展示了它的一個例子:
Listing B
?php $data = array(5,8,1,7,2);rsort($data); print_r($data);
?
它的輸出結果如下:
Array ([0] = 8
[1] = 7
[2] = 5
[3] = 2
[4] = 1
)
根據關鍵字排序
當我們使用數組的時候,經常根據關鍵字對數組重新排序,從高到低。Ksort()函數就是根據關鍵字進行排序的函數,同時,它在排序的過程中會保持關鍵字的相關性。Listing C就是一個例子:
Listing C
?php $data = array(“US” = “United States”, “IN” = “India”, “DE” = “Germany”, “ES” = “Spain”);ksort($data); print_r($data);
?
它的輸出結果如下:
Array ([DE] = Germany
[ES] = Spain
[IN] = India
[US] = United States
)
Krsort()函數是根據關鍵字對數組進行倒排,Listing D就是這樣的例子:
Listing D
?php $data = array(“US” = “United States”, “IN” = “India”, “DE” = “Germany”, “ES” = “Spain”);krsort($data); print_r($data);
?
它的輸出結果如下:
Array ([US] = United States
[IN] = India
[ES] = Spain
[DE] = Germany
)
根據值排序
如果你想使用值排序來取代關鍵字排序的話,PHP也能滿足你的要求。你只要使用asort()函數來代替先前提到的ksort()函數就可以了。如Listing E所示:
Listing E
?php $data = array(“US” = “United States”, “IN” = “India”, “DE” = “Germany”, “ES” = “Spain”);asort($data); print_r($data);
?
下面就是它的輸出結果。請注意這個結果與上面使用ksort()函數所得到的結果的不同——在這兩種情況中,都是按字母順序進行排序的,但是它們是根據數組的不同欄位進行排序的。
同時,請注意關鍵字-值之間的聯繫會始終保持;它只是關鍵字-值對排序後的一種方式,排序並不會改變它們的對應關係。
Array ([DE] = Germany
[IN] = India
[ES] = Spain
[US] = United States
)
現在,你肯定能猜到這種排序也可以進行倒排,它使用arsort()函數完成這個功能。Listing F就是一個例子:
Listing F
?php $data = array(“US” = “United States”, “IN” = “India”, “DE” = “Germany”, “ES” = “Spain”);arsort($data); print_r($data);
?
下面是它的輸出結果,根據值按字母表順序進行倒排。將下面的結果與用krsort()函數進行倒排後生成的結果進行比較,就能很容易明白兩者的不同了。
Array ([US] = United States
[ES] = Spain
[IN] = India
[DE] = Germany
)
自然語言排序
PHP有一個非常獨特的排序方式,這種方式使用認知而不是使用計算規則。這種特性稱為自然語言排序,當創建模糊邏輯應用軟體的時候這種排序方式非常有用。下面大家可以來看看它的一個簡單例子,如Listing G所示:
Listing G
?php $data = array(“book-1”, “book-10”, “book-100”, “book-5”); sort($data);print_r($data);
natsort($data); print_r($data);?
它的輸出結果如下:
Array ([0] = book-1
[1] = book-10
[2] = book-100
[3] = book-5
)
Array
(
[0] = book-1
[3] = book-5
[1] = book-10
[2] = book-100
)
它們的不同已經很清楚了:第二個排序結果更直觀,更「人性化」,然而第一個則更符合演算法規則,更具「計算機」特點。
自然語言能進行倒排嗎?答案是肯定的!只要對natsort()的結果使用array_reverse()函數就可以了,Listing H就是一個簡單例子:
Listing H
?php $data = array(“book-1”, “book-10”, “book-100”, “book-5”);natsort($data); print_r(array_reverse($data));
?
下面是它的輸出結果:
Array ([0] = book-100
[1] = book-10
[2] = book-5
[3] = book-1
)
根據用戶自定義的規則排序
PHP也能讓你定義自己的排序演算法,你可以通過創建你自己的比較函數,並把它傳遞給usort()函數。如果第一個參數比第二個參數「小」的話,比較函數必須返回一個比0小的數,如果第一參數比第二個參數「大」的話,比較函數應該返回一個比0大的數。
Listing I就是這樣的一個例子,在這個例子中根據它們的長度對數組元素進行排序,最短的項放在最前面:
Listing I
?php $data = array(“joe@host.com”, “john.doe@gh.co.uk”, “asmithsonian@us.info”, “jay@zoo.tw”);usort($data, ‘sortByLen’);
print_r($data); function sortByLen($a, $b) {
if (strlen($a) == strlen($b)) {
return 0;
} else {
return (strlen($a) strlen($b)) ? 1 : -1;
}
}
?
這樣,就創建了我們自己的比較函數,這個函數使用strlen()函數比較每一個字元串的個數,然後分別返回1,0或-1.這個返回值是決定元素排列的基礎。下面是它的輸出結果:
Array ([0] = jay@zoo.tw
[1] = joe@host.com
[2] = john.doe@gh.co.uk
[3] = asmithsonian@us.info
)
自然語言排序
PHP有一個非常獨特的排序方式,這種方式使用認知而不是使用計算規則。這種特性稱為自然語言排序,當創建模糊邏輯應用軟體的時候這種排序方式非常有用。下面大家可以來看看它的一個簡單例子,如Listing G所示:
Listing G
?php $data = array(“book-1”, “book-10”, “book-100”, “book-5”); sort($data);print_r($data);
natsort($data); print_r($data);?
它的輸出結果如下:
Array ([0] = book-1
[1] = book-10
[2] = book-100
[3] = book-5
)
Array
(
[0] = book-1
[3] = book-5
[1] = book-10
[2] = book-100
)
它們的不同已經很清楚了:第二個排序結果更直觀,更「人性化」,然而第一個則更符合演算法規則,更具「計算機」特點。
自然語言能進行倒排嗎?答案是肯定的!只要對natsort()的結果使用array_reverse()函數就可以了,Listing H就是一個簡單例子:
Listing H
?php $data = array(“book-1”, “book-10”, “book-100”, “book-5”);natsort($data); print_r(array_reverse($data));
?
下面是它的輸出結果:
Array ([0] = book-100
[1] = book-10
[2] = book-5
[3] = book-1
)
根據用戶自定義的規則排序
PHP也能讓你定義自己的排序演算法,你可以通過創建你自己的比較函數,並把它傳遞給usort()函數。如果第一個參數比第二個參數「小」的話,比較函數必須返回一個比0小的數,如果第一參數比第二個參數「大」的話,比較函數應該返回一個比0大的數。
Listing I就是這樣的一個例子,在這個例子中根據它們的長度對數組元素進行排序,最短的項放在最前面:
Listing I
?php $data = array(“joe@host.com”, “john.doe@gh.co.uk”, “asmithsonian@us.info”, “jay@zoo.tw”);usort($data, ‘sortByLen’);
print_r($data); function sortByLen($a, $b) {
if (strlen($a) == strlen($b)) {
return 0;
} else {
return (strlen($a) strlen($b)) ? 1 : -1;
}
}
?
這樣,就創建了我們自己的比較函數,這個函數使用strlen()函數比較每一個字元串的個數,然後分別返回1,0或-1.這個返回值是決定元素排列的基礎。下面是它的輸出結果:
Array ([0] = jay@zoo.tw
[1] = joe@host.com
[2] = john.doe@gh.co.uk
[3] = asmithsonian@us.info
)
多維排序
最後,PHP也允許在多維數組上執行一些比較複雜的排序——例如,首先對一個嵌套數組使用一個普通的關鍵字進行排序,然後再根據另一個關鍵字進行排序。這與使用SQL的ORDER BY語句對多個欄位進行排序非常相似。為了能更好的明白它是如何工作的,請仔細看Listing J所舉的例子:
Listing J
?php $data = array(array(“id” = 1, “name” = “Boney M”, “rating” = 3),
array(“id” = 2, “name” = “Take That”, “rating” = 1),
array(“id” = 3, “name” = “The Killers”, “rating” = 4),
array(“id” = 4, “name” = “Lusain”, “rating” = 3),
); foreach ($data as $key = $value) {
$name[$key] = $value[‘name’];
$rating[$key] = $value[‘rating’];
}
array_multisort($rating, $name, $data); print_r($data);?
這裡,我們在$data數組中模擬了一個行和列數組。然後,我使用array_multisort()函數對數據集合進行重排,首先是根據rating進行排序,然後,如果rating相等的話,再根據name排序。它的輸出結果如下:
Array ([0] = Array
(
[id] = 2
[name] = Take That
[rating] = 1
) [1] = Array
(
[id] = 1
[name] = Boney M
[rating] = 3
)
[2] = Array
(
[id] = 4
[name] = Lusain
[rating] = 3
)
[3] = Array
(
[id] = 3
[name] = The Killers
[rating] = 4
)
)
array_multisort()函數是PHP中最有用的函數之一,它有非常廣泛的應用範圍。另外,就如你在例子中所看到的,它能對多個不相關的數組進行排序,也可以使用其中的一個元素作為下次排序的基礎,還可以對資料庫結果集進行排序。
這些例子應該讓你對PHP中各種數組排序函數的使用有了初步的了解,也向你展示了一些隱藏在PHP數組處理工具包的內部功能。
最後,祝你能愉快的使用這些功能!
PHP中的快速排序演算法如何實現倒序?
您好,這樣的:
1. 冒泡排序法
* 思路分析:法如其名,就是像冒泡一樣,每次從數組當中 冒一個最大的數出來。
* 比如:2,4,1 // 第一次 冒出的泡是4
* 2,1,4 // 第二次 冒出的泡是 2
* 1,2,4 // 最後就變成這樣
view sourceprint?
01.$arr=array(1,43,54,62,21,66,32,78,36,76,39);
02.function getpao($arr)
03.{
04.$len=count($arr);
05.//設置一個空數組 用來接收冒出來的泡
06.//該層循環控制 需要冒泡的輪數
07.for($i=1;$i$len;$i++)
08.{ //該層循環用來控制每輪 冒出一個數 需要比較的次數
09.for($k=0;$k$len-$i;$k++)
10.{
11.if($arr[$k]$arr[$k+1])
12.{
13.$tmp=$arr[$k+1];
14.$arr[$k+1]=$arr[$k];
15.$arr[$k]=$tmp;
16.}
17.}
18.}
19.return $arr;
20.}
2. 選擇排序法:
選擇排序法思路: 每次選擇一個相應的元素,然後將其放到指定的位置
view sourceprint?
01.function select_sort($arr) {
02.//實現思路 雙重循環完成,外層控制輪數,當前的最小值。內層 控制的比較次數
03.//$i 當前最小值的位置, 需要參與比較的元素
04.for($i=0, $len=count($arr); $i$len-1; $i++) {
05.//先假設最小的值的位置
06.$p = $i;
07.//$j 當前都需要和哪些元素比較,$i 後邊的。
08.for($j=$i+1; $j$len; $j++) {
09.//$arr[$p] 是 當前已知的最小值
10.if($arr[$p] $arr[$j]) {
11.//比較,發現更小的,記錄下最小值的位置;並且在下次比較時,
12.// 應該採用已知的最小值進行比較。
13.$p = $j;
14.}
15.}
16.//已經確定了當前的最小值的位置,保存到$p中。
17.//如果發現 最小值的位置與當前假設的位置$i不同,則位置互換即可
18.if($p != $i) {
19.$tmp = $arr[$p];
20.$arr[$p] = $arr[$i];
21.$arr[$i] = $tmp;
22.}
23.}
24.//返回最終結果
25.return $arr;
26.}
3.插入排序法
插入排序法思路:將要排序的元素插入到已經 假定排序號的數組的指定位置。
view sourceprint?
01.function insert_sort($arr) {
02.//區分 哪部分是已經排序好的
03.//哪部分是沒有排序的
04.//找到其中一個需要排序的元素
05.//這個元素 就是從第二個元素開始,到最後一個元素都是這個需要排序的元素
06.//利用循環就可以標誌出來
07.//i循環控制 每次需要插入的元素,一旦需要插入的元素控制好了,
08.//間接已經將數組分成了2部分,下標小於當前的(左邊的),是排序好的序列
09.for($i=1, $len=count($arr); $i$len; $i++) {
10.//獲得當前需要比較的元素值。
11.$tmp = $arr[$i];
12.//內層循環控制 比較 並 插入
13.for($j=$i-1;$j=0;$j–) {
14.//$arr[$i];//需要插入的元素; $arr[$j];//需要比較的元素
15.if($tmp $arr[$j]) {
16.//發現插入的元素要小,交換位置
17.//將後邊的元素與前面的元素互換
18.$arr[$j+1] = $arr[$j];
19.//將前面的數設置為 當前需要交換的數
20.$arr[$j] = $tmp;
21.} else {
22.//如果碰到不需要移動的元素
23.//由於是已經排序好是數組,則前面的就不需要再次比較了。
24.break;
25.}
26.}
27.}
28.//將這個元素 插入到已經排序好的序列內。
29.//返回
30.return $arr;
31.}
4.快速排序法
view sourceprint?
01.function quick_sort($arr) {
02.//先判斷是否需要繼續進行
03.$length = count($arr);
04.if($length = 1) {
05.return $arr;
06.}
07.//如果沒有返回,說明數組內的元素個數 多餘1個,需要排序
08.//選擇一個標尺
09.//選擇第一個元素
10.$base_num = $arr[0];
11.//遍歷 除了標尺外的所有元素,按照大小關係放入兩個數組內
12.//初始化兩個數組
13.$left_array = array();//小於標尺的
14.$right_array = array();//大於標尺的
15.for($i=1; $i$length; $i++) {
16.if($base_num $arr[$i]) {
17.//放入左邊數組
18.$left_array[] = $arr[$i];
19.} else {
20.//放入右邊
21.$right_array[] = $arr[$i];
22.}
23.}
24.//再分別對 左邊 和 右邊的數組進行相同的排序處理方式
25.//遞歸調用這個函數,並記錄結果
26.$left_array = quick_sort($left_array);
27.$right_array = quick_sort($right_array);
28.//合併左邊 標尺 右邊
29.return array_merge($left_array, array($base_num), $right_array);
30.}
php排序問題
// 冒泡排序
function BubbleSort($arr) {
// 獲得數組總長度
$num = count($arr);
// 正向遍曆數組
for ($i = 1; $i $num; $i++) {
// 反向遍歷
for ($j = $num – 1; $j = $i ; $j–) {
// 相鄰兩個數比較
if ($arr[$j] $arr[$j-1]) {
// 暫存較小的數
$iTemp = $arr[$j-1];
// 把較大的放前面
$arr[$j-1] = $arr[$j];
// 較小的放後面
$arr[$j] = $iTemp;
}
}
}
return $arr;
}
// 交換法排序
function ExchangeSort($arr){
$num = count($arr);
// 遍曆數組
for ($i = 0;$i $num – 1; $i++) {
// 獲得當前索引的下一個索引
for ($j = $i + 1; $j $num; $j++) {
// 比較相鄰兩個的值大小
if ($arr[$j] $arr[$i]) {
// 暫存較小的數
$iTemp = $arr[$i];
// 把較大的放前面
$arr[$i] = $arr[$j];
// 較小的放後面
$arr[$j] = $iTemp;
}
}
}
return $arr;
}
// 選擇法排序
function SelectSort($arr) {
// 獲得數組總長度
$num = count($arr);
// 遍曆數組
for ($i = 0;$i $num-1; $i++) {
// 暫存當前值
$iTemp = $arr[$i];
// 暫存當前位置
$iPos = $i;
// 遍歷當前位置以後的數據
for ($j = $i + 1;$j $num; $j++){
// 如果有小於當前值的
if ($arr[$j] $iTemp) {
// 暫存最小值
$iTemp = $arr[$j];
// 暫存位置
$iPos = $j;
}
}
// 把當前值放到算好的位置
$arr[$iPos] = $arr[$i];
// 把當前值換成算好的值
$arr[$i] = $iTemp;
}
return $arr;
}
// 插入法排序
function InsertSort($arr){
$num = count($arr);
// 遍曆數組
for ($i = 1;$i $num; $i++) {
// 獲得當前值
$iTemp = $arr[$i];
// 獲得當前值的前一個位置
$iPos = $i – 1;
// 如果當前值小於前一個值切未到數組開始位置
while (($iPos = 0) ($iTemp $arr[$iPos])) {
// 把前一個的值往後放一位
$arr[$iPos + 1] = $arr[$iPos];
// 位置遞減
$iPos–;
}
$arr[$iPos+1] = $iTemp;
}
return $arr;
}
// 快速排序
function QuickSort($arr){
$num = count($arr);
$l = $r = 0;
$left = $right = array();
// 從索引的第二個開始遍曆數組
for ($i = 1;$i $num; $i++) {
// 如果值小於索引1
if ($arr[$i] $arr[0]) {
// 裝入左索引數組(小於索引1的數據)
$left[] = $arr[$i];
$l++;
} else {
// 否則裝入右索引中(大於索引1的數據)
$right[] = $arr[$i];
$r++; //
}
}
// 如果左索引有值 則對左索引排序
if($l 1) {
$left = QuickSort($left);
}
// 排序後的數組
$new_arr = $left;
// 將當前數組第一個放到最後
$new_arr[] = $arr[0];
// 如果又索引有值 則對右索引排序
if ($r 1) {
$right = QuickSort($right);
}
// 根據右索引的長度再次增加數據
for($i = 0;$i $r; $i++) {
$new_arr[] = $right[$i];
}
return $new_arr;
}
求助php二維數組的排序
第一種方法:傳說中的冒泡法
function arraysort($data, $order = ‘asc’) {
//asc升序 desc降序
$temp = array ();
$count = count ( $data );
if ($count = 0)
return false; //傳入的數據不正確
if ($order == ‘asc’) {
for($i = 0; $i $count; $i ++) {
for($j = $count – 1; $j $i; $j –) {
if ($data [$j] $data [$j – 1]) {
//交換兩個數據的位置
$temp = $data [$j];
$data [$j] = $data [$j – 1];
$data [$j – 1] = $temp;
}
}
}
} else {
for($i = 0; $i $count; $i ++) {
for($j = $count – 1; $j $i; $j –) {
if ($data [$j] $data [$j – 1]) {
$temp = $data [$j];
$data [$j] = $data [$j – 1];
$data [$j – 1] = $temp;
}
}
}
}
return $data;
}
$data = array (7, 5, 3, 8, 9, 1, 5, 3, 1, 24, 3, 87, 0, 33, 1, 12, 34, 54, 66, 32 );
var_dump ( arraysort ( $data ) ); //升序
echo (‘br’);
var_dump ( arraysort ( $data ,’desc’) );//降序
第二種方法:不知道取個什麼名字好,就叫插入法吧!囧
function arraysort3($data, $order = ‘asc’) {
//目前只做升序排列
$count = count ( $data );
for($i = 1; $i $count; $i ++) {
$temp = $data [$i];
$j = $i – 1;
while ( $data [$j] $temp ) {
$data [$j + 1] = $data [$j];
$data [$j] = $temp;
$j –;//為什麼要遞減:從高位逐位判斷
}
}
return $data;
}
$data = array (7, 5, 3, 8, 9, 1, 5, 3, 1, 24, 3, 87, 0, 33, 1, 12, 34, 54, 66, 32 );
var_dump ( arraysort3 ( $data ) ); //升序
至於列印前十個就不用說了吧 for循環就行
PHP實現常見的排序演算法
註:為方便描述,下面的排序全為正序(從小到大排序)
假設有一個數組[a,b,c,d]
冒泡排序依次比較相鄰的兩個元素,如果前面的元素大於後面的元素,則兩元素交換位置;否則,位置不變。具體步驟:
1,比較a,b這兩個元素,如果ab,則交換位置,數組變為:[b,a,c,d]
2,比較a,c這兩個元素,如果ac,則位置不變,數組變為:[b,a,c,d]
3,比較c,d這兩個元素,如果cd,則交換位置,數組變為:[b,a,d,c]
完成第一輪比較後,可以發現最大的數c已經排(冒)在最後面了,接著再進行第二輪比較,但第二輪比較不必比較最後一個元素了,因為最後一個元素已經是最大的了。
第二輪比較結束後,第二大的數也會冒到倒數第二的位置。
依次類推,再進行第三輪,,,
就這樣最大的數一直往後排(冒),最後完成排序。所以我們稱這種排序演算法為冒泡排序。
選擇排序是一種直觀的演算法,每一輪會選出列中最小的值,把最小值排到前面。具體步驟如下:
插入排序步驟大致如下:
快速排序是由東尼·霍爾所發展的一種排序演算法。在平均狀況下,排序 n 個項目要Ο(n log n)次比較。在最壞狀況下則需要Ο(n2)次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他Ο(n log n) 演算法更快,因為它的內部循環(inner loop)可以在大部分的架構上很有效率地被實現出來,且在大部分真實世界的數據,可以決定設計的選擇,減少所需時間的二次方項之可能性。
步驟:
從數列中挑出一個元素,稱為 「基準」(pivot),
重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分區退出之後,該基準就處於數列的中間位置。這個稱為分區(partition)操作。
遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。
原創文章,作者:OQ8A6,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/129657.html
微信掃一掃
支付寶掃一掃