簡體   English   中英

是否有一種使用二進制樹按數字位數排序的算法?

[英]Is there a kind of sorting algorithm use binary tree by bits of number?

我已經查看了可以找到的排序算法,但是沒有看到任何一種算法使用數字位。 我認為,我創建了一種新型的排序算法。 我命名為Bitsort 描述在github中


您知道這樣的排序算法嗎?


復雜度為O(nk) k是數組元素的位大小。 數組順序並不重要。 每次復雜度為O(nk) 但是它占用了很多內存。 它取決於N。但是當N增加時,內存相對減少。 如果N為1,則為最大內存比率(R = Node / N)(= bitsize) 如果N為最大值,則內存比率降低到R =2。因此R * N是存儲整個位樹需要多少個節點。 如果N等於最大值->(2 ^ 32為整數),我們需要2N個節點來存儲所有數組。 每個節點都有2個地址指針。

同時,N不是數組中的數字計數。 N唯一的數字計數。

如果數組中的所有元素都相同,則N等於1。

總結

    Memory = P*N*R (P: pointer size, N: unique count, R: NodeCount(C)/N)


    I create a formula for R for 32 bit integer.
    R = 31 - 3.3*LOG10(N)

我將數字從MSB(最高有效位)到LSB(最低有效位)放到二叉樹中。 如果以前添加了它們,那么我將增加價值之葉的數量。

我只有1次從頭到尾在源數組上移動,並且“排序樹”已被填充。

void bitSort(int * array, int arraySize) {
    int i, j;
    Block* block;
    clock_t start, end;

    //create a buffer. root node is first node in buffer. 
    root = initBlockBuffer();
    const unsigned long long digit = ((unsigned long long) 1) << (ARRAY_ELEMENT_TYPE_SIZE_1);

    //for every array element (n !IMPORTANT)
    for (i = 0; i < arraySize; i++) {
        // start at root
        Block* activeBlock = root;

        register int value = array[i];
        register int bit;

        //for every bit of value (k !IMPORTANT)
        for (j = 0; j < ARRAY_ELEMENT_TYPE_SIZE_1; j++){

            //from msb to lsb get the bit   
            bit = (digit & (value << j)) >> (ARRAY_ELEMENT_TYPE_SIZE_1);

            // get the related node from bit 
            block = activeBlock->node[bit];


            // if the node is not exists
            if (block == 0) {

                // get next blank node from the buffer.
                block = nextFreeBlock();

                //connect new node to previous node  
                activeBlock->node[bit] = block;
            }

            // jump to new node.
            activeBlock = block;
        }

        //after all last node is leaf. 
        //Getting from last bit of value
        if(activeBlock->cnt[value & 1] == 0) leafCount++;  
        //and count of this leaf, increasing 1
        activeBlock->cnt[value & 1]++;  

    }
}


一些結果


如果我們創建一個具有1000000(一百萬)個4字節整數的數組,則為:-相同的數字-從1增加到1000000-隨機均勻分布


相同的數字

Leaf Count    : 1
Node Count    : 31
Node Size     : 16 byte
Total Memory  : 512 byte
Duration Sort : 178721 us (0.02s)
Duration Read : 4994 us (0.005s)


從1增加到1000000

Leaf Count    : 1000000
Node Count    : 1000018
Node Size     : 16 byte
Total Memory  : 16000304 byte (16MB)
Duration Sort : 218556 us (0.2s)
Duration Read : 14321 us (0.01s)


隨機均勻分布

Leaf Count    : 999768 (uniq numbers, >%0,02 repetition)
Node Count    : 11181318
Node Size     : 16 byte
Total Memory  : 178913456 byte (179MB)
Duration Sort : 1460578 us (1.4s)
Duration Read : 666933 us (0.7s)


有沒有您所知道的算法?


示例:我們假設有3位長度的數字。

array = {7, 3, 2, 5, 0, 7, 3, 2, 7};

L   : level
msb : most significant bit
lsb : least significant bit

              msb       lsb
               L1   L2   L3
7 = 111  -->    1    1    1
3 = 011  -->    0    1    1
2 = 010  -->    0    1    0
5 = 101  -->    1    0    1
0 = 000  -->    0    0    0
7 = 111  -->    1    1    1
3 = 011  -->    0    1    1
2 = 010  -->    0    1    0
7 = 111  -->    1    1    1

首先二叉樹只有根節點。

                        0_____________________|_____________________1                          
                       /                                             \                         

第一個數字使用從msb到lsb的自己的位添加到二叉樹中。 (加數:7 =>(111)(3bit空間))

             0_____________________|_____________________1                          
L1  ----->                                                \                         
                                                 0_________\_________1              
L2  ----------------------------------------->                        \             
                                                                   0___\___1        
L3  ---------------------------------------------------------->             \       
                                                                            [1]     

然后其他人隨之而來。 (加數:3、2、5、0)

                        0_____________________|_____________________1                          
                       /                                             \                         
            0_________/_________1                           0_________\_________1              
           /                     \                         /                     \             
      0___/___1               0___\___1               0___/___1               0___\___1        
     /                       /         \                       \                       \       
   [1]                     [1]         [1]                     [1]                      1     

如果樹中已有數字,則其計數增加1。(數字:7、3、2、7)

                        0_____________________|_____________________1                          
                       /                                             \                        
            0_________/_________1                           0_________\_________1              
           /                     \                         /                     \            
      0___/___1               0___\___1               0___/___1               0___\___1        
     /                       /         \             /         \             /         \       
   [1]                     [2]         [2]                     [1]                     [3]     

遞歸讀取時,可以得到排序數組。

sorted_array =  [1x(000), 2x(010), 2x(011), 1x(101), 3x(111)]
sorted_array =  [1x0, 2x2, 2x3, 1x5, 3x7]
sorted_array =  [0, 2, 2, 3, 3, 5, 7, 7, 7]

好吧,你錯了。 您已經設計了一個排序的二叉樹(這不是您的發明)。 確實,您不需要具有所有鍵(如您在示例中所做的那樣)即可完成樹。 這樣,它的平均運行樹為O(n*log(n)) ,因為每次插入都需要覆蓋所有樹節點,直到您要放置密鑰的地方。 另外,如果您已經獲得有序集合,則該樹將在列表中退化(您始終會轉到右側分支,直到到達插入位置),然后退化為O(n²)

另外,如果要考慮集合中的每個鍵(就像在所有樣本中一樣),則可以通過僅實現大小為2^n的數組並考慮A[n]左兒子來節省指針空間。是索引為2*n的單元格,右子元素為索引2*n+1的單元格。 在這種情況下,您只需要存儲與鍵關聯的數據,而不必存儲指針。 如果考慮構建多維數組(具有與位一樣多的維數)並且每個索引從01的可能性,也會導致這種方法。 在這種情況下,考慮到數組的大小,您可以將數組視為線性數組,將數據直接線性地直接存儲到數組單元中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM