指数树实现

Exponential tree implementation

本文关键字:实现 指数      更新时间:2023-10-16

我试图从文档中实现指数树,但代码中有一个地方我不清楚如何实现:

#include<iostream>
using namespace std;
struct node
{
    int level;
    int count;
    node **child;
    int data[];
};
int binary_search(node *ptr,int element)
{
    if(element>ptr->data[ptr->count-1]) return ptr->count;
    int start=0;
    int end=ptr->count-1;
    int mid=start+(end-start)/2;
    while(start<end)
    {
        if(element>ptr->data[mid]) { start=mid+1;}
        else
        {
            end=mid;
        }
        mid=start+(end-start)/2;
    }
    return mid;
}
void insert(node *root,int element)
{
    node *ptr=root,*parent=NULL;
    int i=0;
    while(ptr!=NULL)
    {
        int level=ptr->level,count=ptr->count;
        i=binary_search(ptr,element);
        if(count<level){
            for(int j=count;j<=i-1;j--)
                ptr->data[j]=ptr->data[j-1];
        }
            ptr->data[i]=element;
            ptr->count=count+1;
            return ;
        }
    parent=ptr,ptr=ptr->child[i];
    //Create a new Exponential Node at ith child of parent and
//insert element in that
    return ;
}
int main()
{

return 0;
}

以下是我所指论文的链接:http://www.ijcaonline.org/volume24/number3/pxc3873876.pdf这个地方在评论中,我如何在i级别创建一个新的指数节点?像这样?

parent->child[i]=new node;
insert(parent,element);

结构末尾的空数组表明这是C风格的代码,而不是C++(这是灵活数组的C Hack)。我将继续使用C风格的代码,因为惯用的C++代码更喜欢使用用于子成员和数据成员的标准容器。

以下代码的一些注释和评论:

  • 链接论文中的伪代码存在许多问题,因此最好忽略它,从头开始开发代码。缩进级别不清楚循环的结束位置,所有循环索引都不正确,查找插入点的检查不正确,等等
  • 我没有包含任何删除分配内存的代码,所以代码会按原样泄漏
  • 零大小的数组可能不是所有编译器都支持的(我相信这是C99的一个特性)。例如,VS2010向我发出警告C4200,说它不会生成默认的复制/分配方法
  • 我添加了createNode()函数,它给出了如何在给定级别分配节点的原始问题的答案
  • 添加了一个非常基本的测试,似乎可以工作,但在我熟悉代码之前,还需要进行更彻底的测试
  • 除了不正确的伪代码外,该论文还有许多其他错误或至少有问题的内容。例如,关于图2,它说"它清楚地描述了图的斜率是线性的",其中图显然不是线性的。即使作者的意思是"接近线性",至少也是在夸大事实。我还对他们用于测试的整数集感兴趣,这些整数似乎根本没有被提及。我假设他们使用了一个随机集,但我希望看到至少使用了几个随机数集,以及几个预定义的集,例如已经排序或反向排序的集

int binary_search(node *ptr, int element)
{
    if (ptr->count == 0) return 0;
    if (element > ptr->data[ptr->count-1]) return ptr->count;   
    int start = 0;
    int end = ptr->count - 1;
    int mid = start + (end - start)/2;
    while (start < end)
    {
        if (element > ptr->data[mid]) 
            start = mid + 1;
        else
            end = mid;
        mid = start + (end - start)/2;
    }
    return mid;
}

node* createNode (const int level)
{
    if (level <= 0) return NULL;
        /* Allocate node with 2**(level-1) integers */
    node* pNewNode = (node *) malloc(sizeof(node) + sizeof(int)*(1 << (level - 1))); 
    memset(pNewNode->data, 0, sizeof(int) * (1 << (level - 1 )));
        /* Allocate 2**level child node pointers */
    pNewNode->child = (node **) malloc(sizeof(node *)* (1 << level));
    memset(pNewNode->child, 0, sizeof(int) * (1 << level));
    pNewNode->count = 0;
    pNewNode->level = level;
    return pNewNode;
}

void insert(node *root, int element)
{
    node *ptr = root;
    node *parent = NULL;
    int i = 0;
    while (ptr != NULL)
    {
        int level = ptr->level;
        int count = ptr->count;
        i = binary_search(ptr, element);
        if (count < (1 << (level-1)))
        {
            for(int j = count; j >= i+1; --j)
                ptr->data[j] = ptr->data[j-1];
            ptr->data[i] = element;
            ++ptr->count;
            return;
        }
        parent = ptr;
        ptr = ptr->child[i];
    }
    parent->child[i] = createNode(parent->level + 1);
    insert(parent->child[i], element);    
}

void InOrderTrace(node *root)
{
    if (root == NULL) return;
    for (int i = 0; i < root->count; ++i)
    {
        if (root->child[i]) InOrderTrace(root->child[i]);
        printf ("%dn", root->data[i]);
    }
    if (root->child[root->count]) InOrderTrace(root->child[root->count]);
}

void testdata (void)
{
    node* pRoot = createNode(1);
    for (int i = 0; i < 10000; ++i)
    {
        insert(pRoot, rand());
    }
    InOrderTrace(pRoot);
}