[讨论]php 排序系列的函数内部的C实现是用了哪种排序算法?
2013-08-16 10:33
483 查看
ext/standard/php_array.h
https://github.com/php/php-src/blob/master/ext/standard/php_array.h
#ifndef PHP_ARRAY_H #define PHP_ARRAY_H PHP_MINIT_FUNCTION(array);
PHP_MSHUTDOWN_FUNCTION(array);
PHP_FUNCTION(ksort);
PHP_FUNCTION(krsort);
PHP_FUNCTION(natsort);
PHP_FUNCTION(natcasesort);
PHP_FUNCTION(asort);
PHP_FUNCTION(arsort);
PHP_FUNCTION(sort);
PHP_FUNCTION(rsort);
PHP_FUNCTION(usort);
PHP_FUNCTION(uasort);
PHP_FUNCTION(uksort);
……
上面定义的排序函数:
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])
Sort an array */ PHP_FUNCTION(sort)
{
zval *array;
long sort_type = PHP_SORT_REGULAR; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &sort_type) == FAILURE) {
RETURN_FALSE;
}
php_set_compare_func(sort_type TSRMLS_CC); if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_data_compare, 1 TSRMLS_CC) == FAILURE) {
RETURN_FALSE;
}
RETURN_TRUE;
}
/* }}} */
在代码中,看到了
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
(*sort_func)((void *) arTmp, i, sizeof(Bucket *), compar TSRMLS_CC);
HANDLE_BLOCK_INTERRUPTIONS();
ht->pListHead = arTmp[0];
ht->pListTail = NULL;
ht->pInternalPointer = ht->pListHead;
arTmp[0]->pListLast = NULL; if (i > 1) {
arTmp[0]->pListNext = arTmp[1]; for (j = 1; j < i-1; j++) {
arTmp[j]->pListLast = arTmp[j-1];
arTmp[j]->pListNext = arTmp[j+1];
}
arTmp[j]->pListLast = arTmp[j-1];
arTmp[j]->pListNext = NULL;
} else {
arTmp[0]->pListNext = NULL;
}
ht->pListTail = arTmp[i-1];
pefree(arTmp, ht->persistent);
HANDLE_UNBLOCK_INTERRUPTIONS(); if (renumber) {
p = ht->pListHead;
i=0; while (p != NULL) {
p->nKeyLength = 0;
p->h = i++;
p = p->pListNext;
}
ht->nNextFreeElement = i;
zend_hash_rehash(ht);
}
在算法中,比快速排序还快的,无疑是基数排序,粗略看了一下算法,可能是基础排序中的hash桶排序。
桶排序是稳定的
桶排序是常见排序里最快的一种,比快排还要快…大多数情况下
桶排序非常快,但是同时也非常耗空间(以空间换时间)
原文链接:http://segmentfault.com/a/1190000000265450
https://github.com/php/php-src/blob/master/ext/standard/php_array.h
#ifndef PHP_ARRAY_H #define PHP_ARRAY_H PHP_MINIT_FUNCTION(array);
PHP_MSHUTDOWN_FUNCTION(array);
PHP_FUNCTION(ksort);
PHP_FUNCTION(krsort);
PHP_FUNCTION(natsort);
PHP_FUNCTION(natcasesort);
PHP_FUNCTION(asort);
PHP_FUNCTION(arsort);
PHP_FUNCTION(sort);
PHP_FUNCTION(rsort);
PHP_FUNCTION(usort);
PHP_FUNCTION(uasort);
PHP_FUNCTION(uksort);
……
上面定义的排序函数:
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])
Sort an array */ PHP_FUNCTION(sort)
{
zval *array;
long sort_type = PHP_SORT_REGULAR; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &sort_type) == FAILURE) {
RETURN_FALSE;
}
php_set_compare_func(sort_type TSRMLS_CC); if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_data_compare, 1 TSRMLS_CC) == FAILURE) {
RETURN_FALSE;
}
RETURN_TRUE;
}
/* }}} */
在代码中,看到了
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
(*sort_func)((void *) arTmp, i, sizeof(Bucket *), compar TSRMLS_CC);
HANDLE_BLOCK_INTERRUPTIONS();
ht->pListHead = arTmp[0];
ht->pListTail = NULL;
ht->pInternalPointer = ht->pListHead;
arTmp[0]->pListLast = NULL; if (i > 1) {
arTmp[0]->pListNext = arTmp[1]; for (j = 1; j < i-1; j++) {
arTmp[j]->pListLast = arTmp[j-1];
arTmp[j]->pListNext = arTmp[j+1];
}
arTmp[j]->pListLast = arTmp[j-1];
arTmp[j]->pListNext = NULL;
} else {
arTmp[0]->pListNext = NULL;
}
ht->pListTail = arTmp[i-1];
pefree(arTmp, ht->persistent);
HANDLE_UNBLOCK_INTERRUPTIONS(); if (renumber) {
p = ht->pListHead;
i=0; while (p != NULL) {
p->nKeyLength = 0;
p->h = i++;
p = p->pListNext;
}
ht->nNextFreeElement = i;
zend_hash_rehash(ht);
}
在算法中,比快速排序还快的,无疑是基数排序,粗略看了一下算法,可能是基础排序中的hash桶排序。
桶排序是稳定的
桶排序是常见排序里最快的一种,比快排还要快…大多数情况下
桶排序非常快,但是同时也非常耗空间(以空间换时间)
原文链接:http://segmentfault.com/a/1190000000265450
相关文章推荐
- php实现排序算法第(二)篇 插入排序 选择排序
- php自带排序函数sort()和用自己用php实现的快速排序算法,速度比较。
- PHP实现指定字段的多维数组排序函数分享
- php实现二维数组排序array_multisort($ages, SORT_DESC, $home)函数
- 约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
- PHP四种排序算法实现及效率分析【冒泡排序,插入排序,选择排序和快速排序】
- php自定义函数实现二维数组排序功能
- PHP排序算法系列之桶排序详解
- php strpos 字符串查找函数内部源码实现
- php中一个用箭头实现的上下排序的函数
- 约瑟夫环问题的 PHP 实现--使用 PHP 数组内部指针操作函数
- 约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
- 使用ob系列函数实现PHP网站页面静态化
- PHP实现指定字段的多维数组排序函数分享
- 不使用PHP内置排序函数对二维数组实现快速排序的面试题
- php strripos 字符串查找函数内部源码实现
- PHP实现排序算法----直接插入排序(Straight Insertion Sort)
- (PHP实现剑指offer)在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
- PHP实现在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
- php自定义函数实现二维数组按指定key排序的方法