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

原创
2016-07-25 08:46:31754浏览

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 < i-1; j++) {
  10. arTmp[j]->pListLast = arTmp[j-1];
  11. arTmp[j]->pListNext = arTmp[j+1];
  12. }
  13. arTmp[j]->pListLast = arTmp[j-1];
  14. arTmp[j]->pListNext = NULL;
  15. } else {
  16. arTmp[0]->pListNext = NULL;
  17. }
  18. ht->pListTail = arTmp[i-1];
  19. pefree(arTmp, ht->persistent);
  20. HANDLE_UNBLOCK_INTERRUPTIONS();
  21. if (renumber) {
  22. p = ht->pListHead;
  23. i=0;
  24. while (p != NULL) {
  25. p->nKeyLength = 0;
  26. p->h = i++;
  27. p = p->pListNext;
  28. }
  29. ht->nNextFreeElement = i;
  30. zend_hash_rehash(ht);
  31. }
复制代码

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

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


声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
上一条:PHP移动互联网开发(1)——环境搭建及配置 下一条:PHP FTP操作类( 上传、拷贝、移动、删除文件/创建目录 )

相关文章

查看更多