Heap Fibonacci

di il
4 risposte

Heap Fibonacci

Sto sviluppando un algoritmo per creare heap di fibonacci, ma il mio problema è legato, credo ad un errore di scrittura...almeno credo, vi posto il codice e l'errore che mi rilascia:
/* File fheap.c - Fibonacci Heap
 * ----------------------------------------------------------------------------
 *  Shane Saunders
 */
#include <cstdlib>
#include <cmath>
#if FHEAP_DUMP
#include <cstdio>
#endif
#include "fheap.h"

/*--- FHeap (public methods) ------------------------------------------------*/

/* --- Constructor ---
 * Creates an FHeap object capable of holding up to $n$ items.
 */
FHeap::FHeap(int n)
{
    int i;
#if FHEAP_DUMP
printf("new, ");
#endif
    maxTrees = 1 + (int) (1.44 * log(n)/log(2.0));
    maxNodes = n;

    trees = new (FHeapNode *)[maxTrees];
    for(i = 0; i < maxTrees; i++) trees[i] =0;

    nodes = new (FHeapNode *)[n];
    for(i = 0; i < n; i++) nodes[i] = 0;

    itemCount = 0;

    /* The $treeSum$ of the heap helps to keep track of the maximum rank while
     * nodes are inserted or deleted.
     */
    treeSum = 0;

    /* For experimental purposes, we keep a count of the number of key
     * comparisons.
     */
    compCount = 0;

#if FHEAP_DUMP
printf("new-exited, ");
#endif
}

/* --- Destructor ---
 */
FHeap::~FHeap()
{
    int i;
    
#if FHEAP_DUMP
printf("delete, ");
#endif

    for(i = 0; i < maxNodes; i++) delete nodes[i];
    delete [] nodes;
    delete [] trees;
    
#if FHEAP_DUMP
printf("delete-exited, ");
#endif
}

/* --- insert() ---
 * Inserts an item $item$ with associated key $k$ into the heap.
 */
void FHeap::insert(int item, long k)
{
    FHeapNode *newNode;

#if FHEAP_DUMP
printf("insert, ");
#endif

    /* create an initialise the new node */
    newNode = new FHeapNode;
    newNode->child = NULL;
    newNode->left = newNode->right = newNode;
    newNode->rank = 0;
    newNode->item = item;
    newNode->key = k;

    /* maintain a pointer to $item$'s new node in the heap */
    nodes[item] = newNode;

    /* meld the new node into the heap */
    meld(newNode);

    /* update the heaps node count */
    itemCount++;

#if FHEAP_DUMP
printf("insert-exited, ");
#endif
}

/* --- deleteMin() ---
 * Deletes and returns the minimum item from the heap.
 */
int FHeap::deleteMin()
{
    FHeapNode *minNode, *child, *next;
    long k, k2;
    int r, v, item;

#if FHEAP_DUMP
printf("deleteMin, ");
#endif

    /* First we determine the maximum rank in the heap. */
    v = treeSum;
    r = -1;
    while(v) {
        v = v >> 1;
        r++;
    };

    /* Now determine which root node is the minimum. */
    minNode = trees[r];
    k = minNode->key;
    while(r > 0) {
        r--;
        next = trees[r];
        if(next) {
            if((k2 = next->key) < k) {
                k = k2;
                minNode = next;
            }
            compCount++;
        }
    }

    /* We remove the minimum node from the heap but keep a pointer to it. */
    r = minNode->rank;
    trees[r] = NULL;
    treeSum -= (1 << r);

    child = minNode->child;
    if(child) meld(child);

    /* Record the vertex no of the old minimum node before deleting it. */
    item = minNode->item;
    nodes[item] = NULL;
    delete minNode;
    itemCount--;

#if FHEAP_DUMP
printf("deleteMin-exited, ");
#endif

    return item;
}

/* --- decreaseKey() ---
 * Decreases the key used for item $item$ to the value newValue.  It is left
 * for the user to ensure that newValue is in-fact less than the current value
 */
void FHeap::decreaseKey(int item, long newValue)
{
    FHeapNode *cutNode, *parent, *newRoots, *r, *l;
    int prevRank;

#if FHEAP_DUMP
printf("decreaseKey on vn = %d, ", item);
#endif

    /* Obtain a pointer to the decreased node and its parent then decrease the
     * nodes key.
     */
    cutNode = nodes[item];
    parent = cutNode->parent;
    cutNode->key = newValue;

    /* No reinsertion occurs if the node changed was a root. */
    if(!parent) {
#if FHEAP_DUMP
printf("decreaseKey-exited, ");
#endif
        return;
    }

    /* Update the left and right pointers of cutNode and its two neighbouring
     * nodes.
     */
    l = cutNode->left;
    r = cutNode->right;
    l->right = r;
    r->left = l;
    cutNode->left = cutNode->right = cutNode;

    /* Initially the list of new roots contains only one node. */
    newRoots = cutNode;

    /* While there is a parent node that is marked a cascading cut occurs. */
    while(parent && parent->marked) {

        /* Decrease the rank of cutNode's parent and update its child pointer.
         */
        parent->rank--;
        if(parent->rank) {
            if(parent->child == cutNode) parent->child = r;
        }
        else {
            parent->child = NULL;
        }

        /* Update the cutNode and parent pointers to the parent. */
        cutNode = parent;
        parent = cutNode->parent;

        /* Update the left and right pointers of cutNodes two neighbouring
         * nodes.
         */
        l = cutNode->left;
        r = cutNode->right;
        l->right = r;
        r->left = l;

        /* Add cutNode to the list of nodes to be reinserted as new roots. */
        l = newRoots->left;
        newRoots->left = l->right = cutNode;
        cutNode->left = l;
        cutNode->right = newRoots;
        newRoots = cutNode;
    }

    /* If the root node is being relocated then update the trees[] array.
     * Otherwise mark the parent of the last node cut.
     */
    if(!parent) {
        prevRank = cutNode->rank + 1;
        trees[prevRank] = NULL;
        treeSum -= (1 << prevRank);
    }
    else {
        /* Decrease the rank of cutNode's parent an update its child pointer.
         */
        parent->rank--;
        if(parent->rank) {
            if(parent->child == cutNode) parent->child = r;
        }
        else {
            parent->child = NULL;
        }

        parent->marked = 1;
    }

    /* Meld the new roots into the heap. */
    meld(newRoots);

#if FHEAP_DUMP
printf("decreaseKey-exited, ");
#endif
}

/*--- FHeap (private methods) -----------------------------------------------*/

/* --- meld() ---
 * melds the linked list of trees pointed to by $treeList$ into the heap.
 */
void FHeap::meld(FHeapNode *treeList)
{
    FHeapNode *first, *next, *nodePtr, *newRoot, *temp, *temp2, *lc, *rc;
    int r;

#if FHEAP_DUMP
printf("meld: ");
#endif

    /* We meld each tree in the circularly linked list back into the root level
     * of the heap.  Each node in the linked list is the root node of a tree.
     * The circularly linked list uses the sibling pointers of nodes.  This
     *  makes melding of the child nodes from a deleteMin operation simple.
     */
    nodePtr = first = treeList;

    do {

#if FHEAP_DUMP
printf("%d, ", nodePtr->item);
#endif

        /* Keep a pointer to the next node and remove sibling and parent links
         * from the current node.  nodePtr points to the current node.
         */
        next = nodePtr->right;
        nodePtr->right = nodePtr->left = nodePtr;
        nodePtr->parent = NULL;

        /* We merge the current node, nodePtr, by inserting it into the
         * root level of the heap.
         */
        newRoot = nodePtr;
        r = nodePtr->rank;

        /* This loop inserts the new root into the heap, possibly restructuring
         * the heap to ensure that only one tree for each degree exists.
         */
        do {

            /* Check if there is already a tree of degree r in the heap.
             * If there is then we need to link it with newRoot so it will be
             * reinserted into a new place in the heap.
             */
            if((temp = trees[r])) {

	        /* temp will be linked to newRoot and relocated so we no
                 * longer will have a tree of degree r.
                 */
                trees[r] = NULL;
                treeSum -= (1 << r);

	        /* Swap temp and newRoot if necessary so that newRoot always
                 * points to the root node which has the smaller key of the
                 * two.
                 */
	        if(temp->key < newRoot->key) {
                    temp2 = newRoot;
                    newRoot = temp;
                    temp = temp2;
                }
                compCount++;

                /* Link temp with newRoot, making sure that sibling pointers
                 * get updated if rank is greater than 0.  Also, increase r for
                 * the next pass through the loop since the rank of new has
                 * increased.
                 */
	        if(r++ > 0) {
                    rc = newRoot->child;
                    lc = rc->left;
                    temp->left = lc;
                    temp->right = rc;
                    lc->right = rc->left = temp;
                }
                newRoot->child = temp;
                newRoot->rank = r;
                temp->parent = newRoot;
                temp->marked = 0;
            }
            /* Otherwise if there is not a tree of degree r in the heap we
             * allow newRoot, which possibly carries moved trees in the heap,
             * to be a tree of degree r in the heap.
             */
            else {

                trees[r] = newRoot;
                treeSum += (1 << r);;

                /* NOTE:  Because newRoot is now a root we ensure it is
                 *        marked.
                 */
                newRoot->marked = 1;
	    }

            /* Note that temp will be NULL if and only if there was not a tree
             * of degree r.
             */
        } while(temp);

        nodePtr = next;

    } while(nodePtr != first);

#if FHEAP_DUMP
printf("meld-exited, ");
#endif
}

/*--- FHeap (debugging) -----------------------------------------------------*/

/* --- dumpNodes() ---
 * Recursively print a text representation of the node subtree starting at the
 * node poined to by $node$, using an indentationlevel of $level$.
 */
void FHeap::dumpNodes(FHeapNode *node, int level)
{
#if FHEAP_DUMP
     FHeapNode *childNode, *partner;
     int i, childCount;

     /* Print leading whitespace for this level. */
     for(i = 0; i < level; i++) printf("   ");

     printf("%d(%ld)[%d]\n", node->item, node->key, node->rank);
     
     if((childNode = node->child)) {
	 childNode = node->child->right;
	 
         childCount = 0;

         do {
             dumpNodes(childNode, level+1);
	     if(childNode->dim > node->dim) {
                 for(i = 0; i < level+1; i++) printf("   ");
		 printf("error(dim)\n");  exit(1);
	     }
	     if(childNode->parent != node) {
                 for(i = 0; i < level+1; i++) printf("   ");
		 printf("error(parent)\n");
	     }
             childNode = childNode->right;
	     childCount++;
         } while(childNode != node->child->right);

         if(childCount != node->dim) {
	     for(i = 0; i < level; i++) printf("   ");
             printf("error(childCount)\n");  exit(1);
         }
     }
     else { 
         if(node->dim != 0) {
             for(i = 0; i < level; i++) printf("   ");
	     printf("error(dim)\n"); exit(1);
	 }
     }
#endif
}

/* --- dump() ---
 * Print a text representation of the heap to the standard output.
 */
void FHeap::dump() const
{
#if FHEAP_DUMP
    int i;
    FHeapNode *node;

    printf("\n");
    printf("treeSum = %d\n", treeSum);
    printf("array entries 0..maxTrees =");
    for(i = 0; i < maxTrees; i++) {
        printf(" %d", trees[i] ? 1 : 0 );
    }
    printf("\n\n");
    for(i = 0; i < maxTrees; i++) {
        if((node = trees[i])) {
            printf("tree %d\n\n", i);
            dumpNodes(node, 0);
	    printf("\n");
        }
    }
    fflush(stdout);
#endif    
}


/*---------------------------------------------------------------------------*/
L'errore che mi dà è il seguente:

root@ExKenzo:/home/gengis/Documenti/Algoritmi e Strutture dati/HEAP FIBONACCI# g++ fheap.cpp
fheap.cpp: In constructor ‘FHeap::FHeap(int)’:
fheap.cpp:26: error: array bound forbidden after parenthesized type-id
fheap.cpp:26: note: try removing the parentheses around the type-id
fheap.cpp:29: error: array bound forbidden after parenthesized type-id
fheap.cpp:29: note: try removing the parentheses around the type-id
root@ExKenzo:/home/gengis/Documenti/Algoritmi e Strutture dati/HEAP FIBONACCI#


Mi sapresta dare un suggerimento al riguardo?
Vi ringrazio immensamente!

Kenzo

4 Risposte

  • Re: Heap Fibonacci

    Basta seguire il suggerimento del compilatore. togli le parentesi nelle righe dove compare l'errore.
  • Re: Heap Fibonacci

    Perfetto, ho tolto le parentesi al Type Id, e quegli errori non mi si presentano, però mi si presenta adesso questo:

    root@ExKenzo:/home/../../../HEAP FIBONACCI# g++ fheap.cpp
    /usr/lib/gcc/i486-linux-gnu/4.4.3/../../../../lib/crt1.o: In function `_start':
    (.text+0x18): undefined reference to `main'
    collect2: ld returned 1 exit status
    root@ExKenzo:/home/../../../HEAP FIBONACCI#



    cosa sarebbe ciò?
  • Re: Heap Fibonacci

    Ho trovato questo topic: http://fixunix.com/linux/6304-undefined-reference-main.html
    Interessante...quindi non avrei il main()...in effetti, è vero!
    che gnorri!!

    Lo interisco poi vedo se risolvo i problemi... e aggiorno questo topic.
  • Re: Heap Fibonacci

    Come posso fare il main nel suddetto programma?
Devi accedere o registrarti per scrivere nel forum
4 risposte