我知道uasort是用自定义的排序函数来排序,但是不是想了解他是怎么排序的,算法是用冒泡?
不是说php是用c写的吗,那我下个看看c写这个函数的源代码,哪位大哥有给下啊

解决方案 »

  1.   

    不是自定义的排序函数,而是自定义的比较函数,就是说让你自己写函数判断谁大谁小,排序还是他给你排
    原文 uasort — Sort an array with a user-defined comparison function and maintain index association附5.2.10相关代码(偷懒没下最新的)/* {{{ proto bool uasort(array array_arg, string cmp_function)
       Sort an array with a user-defined comparison function and maintain index association */
    PHP_FUNCTION(uasort)
    {
    zval **array;
    HashTable *target_hash;
    PHP_ARRAY_CMP_FUNC_VARS; PHP_ARRAY_CMP_FUNC_BACKUP(); if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &array, &BG(user_compare_func_name)) == FAILURE) {
    PHP_ARRAY_CMP_FUNC_RESTORE();
    WRONG_PARAM_COUNT;
    }
    target_hash = HASH_OF(*array);
    if (!target_hash) {
    php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array");
    PHP_ARRAY_CMP_FUNC_RESTORE();
    RETURN_FALSE;
    } PHP_ARRAY_CMP_FUNC_CHECK(BG(user_compare_func_name))
    BG(user_compare_fci_cache).initialized = 0; if (zend_hash_sort(target_hash, zend_qsort, array_user_compare, 0 TSRMLS_CC) == FAILURE) {
    PHP_ARRAY_CMP_FUNC_RESTORE();
    RETURN_FALSE;
    }
    PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_TRUE;
    }
    /* }}} */
      

  2.   

    ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func,
    compare_func_t compar, int renumber TSRMLS_DC)
    {
    Bucket **arTmp;
    Bucket *p;
    int i, j; IS_CONSISTENT(ht); if (!(ht->nNumOfElements>1) && !(renumber && ht->nNumOfElements>0)) { /* Doesn't require sorting */
    return SUCCESS;
    }
    arTmp = (Bucket **) pemalloc(ht->nNumOfElements * sizeof(Bucket *), ht->persistent);
    if (!arTmp) {
    return FAILURE;
    }
    p = ht->pListHead;
    i = 0;
    while (p) {
    arTmp[i] = p;
    p = p->pListNext;
    i++;
    } (*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);
    }
    return SUCCESS;
    }/*
       +----------------------------------------------------------------------+
       | Zend Engine                                                          |
       +----------------------------------------------------------------------+
       | Copyright (c) 1998-2009 Zend Technologies Ltd. (http://www.zend.com) |
       +----------------------------------------------------------------------+
       | This source file is subject to version 2.00 of the Zend license,     |
       | that is bundled with this package in the file LICENSE, and is        | 
       | available through the world-wide-web at the following url:           |
       | http://www.zend.com/license/2_00.txt.                                |
       | If you did not receive a copy of the Zend license and are unable to  |
       | obtain it through the world-wide-web, please send a note to          |
       | [email protected] so we can mail you a copy immediately.              |
       +----------------------------------------------------------------------+
       | Authors: Sterling Hughes <[email protected]>                          |
       +----------------------------------------------------------------------+
    *//* $Id: zend_qsort.c,v 1.8.2.1.2.3 2008/12/31 11:17:33 sebastian Exp $ */#include "zend.h"#include <limits.h>#define QSORT_STACK_SIZE (sizeof(size_t) * CHAR_BIT)static void _zend_qsort_swap(void *a, void *b, size_t siz)
    {
    register char  *tmp_a_char;
    register char  *tmp_b_char;
    register int   *tmp_a_int;
    register int   *tmp_b_int;
    register size_t i;
    int             t_i;
    char            t_c; tmp_a_int = (int *) a;
    tmp_b_int = (int *) b; for (i = sizeof(int); i <= siz; i += sizeof(int)) {
    t_i = *tmp_a_int;
    *tmp_a_int++ = *tmp_b_int;
    *tmp_b_int++ = t_i;
    } tmp_a_char = (char *) tmp_a_int;
    tmp_b_char = (char *) tmp_b_int; for (i = i - sizeof(int) + 1; i <= siz; ++i) {
    t_c = *tmp_a_char;
    *tmp_a_char++ = *tmp_b_char;
    *tmp_b_char++ = t_c;
    }
    }ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t compare TSRMLS_DC)
    {
    void           *begin_stack[QSORT_STACK_SIZE];
    void           *end_stack[QSORT_STACK_SIZE];
    register char  *begin;
    register char  *end;
    register char  *seg1;
    register char  *seg2;
    register char  *seg2p;
    register int    loop;
    uint            offset; begin_stack[0] = (char *) base;
    end_stack[0]   = (char *) base + ((nmemb - 1) * siz); for (loop = 0; loop >= 0; --loop) {
    begin = begin_stack[loop];
    end   = end_stack[loop]; while (begin < end) {
    offset = (end - begin) >> 1;
    _zend_qsort_swap(begin, begin + (offset - (offset % siz)), siz); seg1 = begin + siz;
    seg2 = end; while (1) {
    for (; seg1 < seg2 && compare(begin, seg1 TSRMLS_CC) > 0;
         seg1 += siz); for (; seg2 >= seg1 && compare(seg2, begin TSRMLS_CC) > 0;
         seg2 -= siz);

    if (seg1 >= seg2)
    break;

    _zend_qsort_swap(seg1, seg2, siz); seg1 += siz;
    seg2 -= siz;
    } _zend_qsort_swap(begin, seg2, siz); seg2p = seg2;

    if ((seg2p - begin) <= (end - seg2p)) {
    if ((seg2p + siz) < end) {
    begin_stack[loop] = seg2p + siz;
    end_stack[loop++] = end;
    }
    end = seg2p - siz;
    }
    else {
    if ((seg2p - siz) > begin) {
    begin_stack[loop] = begin;
    end_stack[loop++] = seg2p - siz;
    }
    begin = seg2p + siz;
    }
    }
    }
    }/* 
     * Local Variables:
     * c-basic-offset: 4 
     * tab-width: 4
     * End:
     * vim600: fdm=er
     * vim: noet sw=4 ts=4
     */