欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

[讨论]php 排序系列的函数内部的C实现是用了哪种排序算法?

程序员文章站 2022-03-30 10:07:23
...

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(array);
  4. PHP_MSHUTDOWN_FUNCTION(array);
  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

  1. /* {{{ proto bool sort(array &array_arg [, int sort_flags])
  2. Sort an array */
  3. PHP_FUNCTION(sort)
  4. {
  5. zval *array;
  6. long sort_type = PHP_SORT_REGULAR;
  7. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &sort_type) == FAILURE) {
  8. RETURN_FALSE;
  9. }
  10. php_set_compare_func(sort_type TSRMLS_CC);
  11. if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_data_compare, 1 TSRMLS_CC) == FAILURE) {
  12. RETURN_FALSE;
  13. }
  14. RETURN_TRUE;
  15. }
  16. /* }}} */
复制代码

在代码中,看到了

if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_data_compare, ……

使用快速排序的可能性大。

继续分析。

Zend/zend_hash.c

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

  1. (*sort_func)((void *) arTmp, i, sizeof(Bucket *), compar TSRMLS_CC);
  2. HANDLE_BLOCK_INTERRUPTIONS();
  3. ht->pListHead = arTmp[0];
  4. ht->pListTail = NULL;
  5. ht->pInternalPointer = ht->pListHead;
  6. arTmp[0]->pListLast = NULL;
  7. if (i > 1) {
  8. arTmp[0]->pListNext = arTmp[1];
  9. for (j = 1; j arTmp[j]->pListLast = arTmp[j-1];
  10. arTmp[j]->pListNext = arTmp[j+1];
  11. }
  12. arTmp[j]->pListLast = arTmp[j-1];
  13. arTmp[j]->pListNext = NULL;
  14. } else {
  15. arTmp[0]->pListNext = NULL;
  16. }
  17. ht->pListTail = arTmp[i-1];
  18. pefree(arTmp, ht->persistent);
  19. HANDLE_UNBLOCK_INTERRUPTIONS();
  20. if (renumber) {
  21. p = ht->pListHead;
  22. i=0;
  23. while (p != NULL) {
  24. p->nKeyLength = 0;
  25. p->h = i++;
  26. p = p->pListNext;
  27. }
  28. ht->nNextFreeElement = i;
  29. zend_hash_rehash(ht);
  30. }
复制代码

在算法中,比快速排序还快的,无疑是基数排序,粗略看了一下算法,可能是基础排序中的hash桶排序

桶排序是稳定的 桶排序是常见排序里最快的一种,比快排还要快…大多数情况下 桶排序非常快,但是同时也非常耗空间(以空间换时间
用了, 哪种, php