ホームページ  >  記事  >  バックエンド開発  >  [考察] PHP ソート系列関数の C 実装ではどのソート アルゴリズムが使用されていますか?

[考察] PHP ソート系列関数の C 実装ではどのソート アルゴリズムが使用されていますか?

WBOY
WBOYオリジナル
2016-07-25 08:46:311076ブラウズ

ext/standard/php_array.h

https://github.com/php/php-src/blob/master/ext/standard/php_array.h

  1. #ifndef PHP_ARRAY_H
  2. #define PHP_ARRAY_H
  3. PHP_MINIT_FUNCTION(配列);
  4. PHP_MSHUTDOWN_FUNCTION(配列);
  5. PHP_FUNCTION(ksort);
  6. PHP_FUNCTION(krsort);
  7. PHP_FUNCTION(natsort);
  8. PHP_FUNCTION(natcasesort);
  9. PHP_FUNCTION(asort);
  10. PHP_FUNCTION(arsort);
  11. PHP_FUNCTION(sort);
  12. PHP_FUNCTION(rsort);
  13. PHP_FUNCTION(usort);
  14. PHP_FUNCTION(uasort);
  15. PHP_FUNCTION(uksort);
  16. ...
コピーコード

上記で定義された並べ替え関数:

arsort -- インデックスの関係を維持しながら、配列を逆順にソートします。 asort – インデックス関係を維持しながら配列をソートする krsort -- 配列をキー名で逆順にソートします。 ksort -- 配列をキーでソートする natcasesort -- 「自然ソート」アルゴリズムを使用して、大文字と小文字を区別しない方法で配列をソートします。 natsort -- 「自然ソート」アルゴリズムを使用して配列をソートします。 rsort -- 配列を逆順にソートします sort -- 配列を並べ替えます uasort – ユーザー定義の比較関数を使用して配列内の値を並べ替え、インデックスの関連付けを維持します uksort -- ユーザー定義の比較関数を使用して配列内のキーを並べ替えます。 usort – ユーザー定義の比較関数を使用して配列内の値を並べ替えます

簡単にするために、sort 関数のみを分析します: https://github.com/php/php-src/blob/master/ext/standard/array.c

{/ *{{Proto Bool Sort (Array & Array_arg [, Int Sort_flags])
配列を並べ替える */
Php_function (sort) {
    zval *array;
  1. long sort_type = p Hp_sort_ Regular
  2. if (zend_parse_parameters(ZEND_NUM_ARGS( ) TSRMLS_CC, "a|l", &array, &sort_type) == FAILURE) {
  3. RETURN_FALSE;
  4. }
  5. php_set_compare_func(sort_type TSRMLS_CC);
  6. if (zend_hash_sort(Z_ARRVAL_P(array), zend_q sort, data_compare、1 TSRMLS_CC) == 失敗) {
  7. RETURN_FALSE;
  8. }
  9. RETURN_TRUE;
  10. }
  11. /* }}} */
  12. コードをコピー
コード内で、私は次のことを確認しました
if (zend_hash_sort(Z_ARRVAL_P(配列), zend_qsort, php_array_data_compare, ……
クイックソートを使用する可能性が高い。

分析を続けます。

Zend/zend_hash.c

https://github.com/php/php-src/blob/master/Zend/zend_hash.c

(*sort_func)((void *) arTmp, i, sizeof(Bucket *), compar TSRMLS_CC);

HANDLE_BLOCK_INTERRUPTIONS();
ht->pListHead = arTmp[0];
    ht-> pListTail = NULL;
  1. ht->pInternalPointer = ht->pListHead;
  2. arTmp[0]->pListLast = NULL;
  3. if (i > 1) {
  4. arTmp[0]->pListNext = arTmp [1];
  5. for (j = 1; j arTmp[j]->pListLast = arTmp[j-1];
  6. arTmp[j]->pListNext = arTmp[ j+1];
  7. }
  8. arTmp[j]->pListLast = arTmp[j-1];
  9. arTmp[j]->pListNext = NULL;
  10. } else {
  11. arTmp[0]->pListNext = NULL;
  12. }
  13. ht->pListTail = arTmp[i-1];
  14. pefree(arTmp, ht->persistent);
  15. HANDLE_UNBLOCK_INTERRUPTIONS();
  16. if (renumber) {
  17. p = ht->; pListHead;
  18. i=0;
  19. while (p != NULL) {
  20. p->nKeyLength = 0;
  21. p->h = i++;
  22. p = p->pListNext;
  23. }
  24. ht-> nNextFreeElement = i;
  25. zend_hash_rehash(ht);
  26. }
  27. コードをコピー
アルゴリズムの中で、クイックソートよりも速いのは間違いなく基数ソートです。アルゴリズムをざっと見てみると、それは基本的なソートの
ハッシュバケットソートかもしれません。 バケットソートが安定している バケット ソートは最も高速な一般的なソートであり、ほとんどの場合、クイック ソートよりも高速です。 バケットのソートは非常に高速ですが、多くのスペースも消費します (
スペースを時間と交換する

)

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