int main( ) { int numItems = 10000; BinomialQueue<int> h; BinomialQueue<int> h1; BinomialQueue<int> h2; int i = 37; for( i = 37; i != 0; i = ( i + 37 ) % numItems ) if( i % 2 == 0 ) h1.insert( i ); else h.insert( i ); h.merge( h1 ); h2 = h; for( i = 1; i < numItems; i++ ) { int x; h2.deleteMin( x ); if( x != i ) cout << "Oops! " << i << endl; } if( !h1.isEmpty( ) ) cout << "Oops! h1 should have been empty!" << endl; return 0; }
// // This file contains the C++ code from Program 11.20 of // "Data Structures and Algorithms // with Object-Oriented Design Patterns in C++" // by Bruno R. Preiss. // // Copyright (c) 1998 by Bruno R. Preiss, P.Eng. All rights reserved. // // http://www.pads.uwaterloo.ca/Bruno.Preiss/books/opus4/programs/pgm11_20.cpp // Object& BinomialQueue::DequeueMin () { if (count == 0) throw domain_error ("priority queue is empty"); BinomialTree& minTree = FindMinTree (); RemoveTree (minTree); BinomialQueue queue; while (minTree.Degree () > 0) { BinomialTree& child = minTree.Subtree (0); minTree.DetachSubtree (child); queue.AddTree (child); } Merge (queue); Object& result = minTree.Key (); minTree.RescindOwnership (); delete &minTree; return result; }
void graph<vertex_type>::DijkstraPath( const vertex_type & start_vertex ) { BinomialQueue< vertex<vertex_type> > q; for(auto pair: graph_) { pair.second->clearDijkstra(); } vertex<vertex_type>* s = (graph_[start_vertex]); s->dist = 0; q.insert(*s); while( !q.isEmpty() ) { vertex<vertex_type> v; q.deleteMin(v); graph_[v.name]->known = true; //cout << "\n@@@@@@@@@@@DEQUEUED: graph_[v.name]: " << graph_[v.name]->name << " @@@@@@@@@@@" << endl; for(auto w : v.adj) //adj is: list< pair <vertex<vertex_type>*, double> > adj if( !(w.first)->known ) { //cout << "\ngraph_[w.first->name] " << graph_[w.first->name]->name << endl; DistType cost_v_to_w = w.second; if( v.dist + cost_v_to_w < (w.first)->dist ) { //cout << " w: " << (w.first->name) << endl; q.decreaseKey( *(w.first), (v.dist + cost_v_to_w) ); w.first->dist = (v.dist + cost_v_to_w); w.first->path = graph_[v.name]; if(!q.contains( *(w.first) ) ) q.insert( *(w.first) ); } } //cout << "q.isEmpty() : " << q.isEmpty() << endl; } }
void testBQ( const string & fileName ) { cout << "\n********** Priority queues **********\n\n"; ifstream f1; f1.open( fileName.c_str() ); if( f1.fail( ) ){ cout << "Error opening " << fileName; exit( 1 ); } int numItems = 10000; cout << "Part 1. Inserting words in Binomial Queue\n"; BinomialQueue BQ; HashTable HT ( BUCKET_SIZE ); string wordToSearch, line; int numberOfLines = 1; BQ.setNumberOfComparisonsAndAssignments( 0, 0 ); while( f1 ){ // read the document file getline( f1, line ); string::iterator it; for( it = line.begin( ); it < line.end( ); it++ ){ if( isspace( *it ) || ( ispunct( *it ) && *it != 39) ){ // || *it == 34){ if( wordToSearch != "" && !HT.contains( wordToSearch ) ){ BinomialNode *bn = BQ.insert( wordToSearch, numberOfLines ); // BinomialNode *bn = BQ.insertFast( wordToSearch, numberOfLines ); HT.insert( wordToSearch , bn ); } else if( HT.contains( wordToSearch ) ){ HT.updateLineNumberForWord( wordToSearch, numberOfLines ); } wordToSearch.clear(); continue; } else{ wordToSearch += *it; // build up the word } } numberOfLines++; line.clear(); // prepare to read a new line } cout << BQ.getCurrentSize( ) << " items inserted in Binomial Queue\n\n"; // BQ.printRoots( ); // debugging /************************************************************ * (2) Count and print out the total number of comparisons * and assignments executed for the insertions of all the * N elements into the binomial queue. ***********************************************************/ cout << "Part 2. Print out number of operations\n"; cout << "Number of comparisons : " << BQ.getCmps( ) << endl; cout << "Number of assignments : " << BQ.getAsmts( ) << endl; /************************************************************ * (3) Test the deleteMin() operation by applying a sequence * of 10 deleteMin() and by printing out the result (i.e. key * deleted along with associated line numbers). ***********************************************************/ cout << "\nPart 3. "; cout << "Executing 10 deleteMin() operations:\n"; for( int i = 0; i < 10; ++i ){ string minValue = BQ.findMin( ); // save element for printing line numbers cout << "Min. val.: " << setw( 10 ) << left << minValue << " "; // print element HT.printLineNumbersForWord( minValue ); BQ.deleteMin( ); // delete here. HT.remove( minValue ); } cout << endl; /************************************************************ * (4) Test the function find() as follows: Prompt the user * to input a string key. Execute the private function * find(key). If find returns a pointer to a node that indeed * holds key printout that find() was successful; printout * the set of line numbers as well. Otherwise, printout that * find() did not find the key. ***********************************************************/ cout << "Part 4. Testing find() function [once]:\n"; cout << "Enter a string key: "; string key; cin >> key; BinomialNode *keyNode1 = HT.find( key ); if( keyNode1 ){ cout << "find() function found the key \"" << key << "\""; cout << " in lines: "; HT.printLineNumbersForWord( key ); cout << endl; } else{ cout << "find() function did not find the key \"" << key << "\"" << endl; } // delete keyNode1; /****************************************************************** * (5) You are ready to implement now the remove(key) operation. * For a given key, find its position p (p is a pointer) in the * priority queue using the hash table. If the key is found delete * it from the bq (Hint: your code should percolate the key up all * the way to the root and then delete the root). Test your * implementation by applying a sequence of remove(key) operations, * and verify their correctness. For instance after remove(key), * find(key) should return “not found”. Prompt the user 5 times * to input a key. Execute then the remove(key) operation and * verify (by printing whether the removal was successful or not). *****************************************************************/ cout << "Part 5. Removing 5 keys and verifying the result" << endl; key = ""; // BinomialNode *keyNode2; for( int i = 0; i < 5; ++i ){ cout << "Enter a key to remove: "; cin >> key; BinomialNode *keyNode2 = HT.find( key ); if( keyNode2 ){ cout << "The key: \"" << key << "\" is removed " << endl; BQ.remove( keyNode2 ); // remove from Binomial Queue HT.remove( key ); // update Hash Table as well cout << "Trying to find it..." << endl; BinomialNode *temp = HT.find( key ); if( temp ) // this should not happen cout << "Hmm.. \"" << temp->element << "\" found!" << endl; else // good! cout << "Good! Deletion is successful" << endl; // cout << BQ.getCurrentSize( ); // debugging // BQ.printRoots( ); } else{ cout << "Cannot remove because the key \"" << key << "\" was not found" << endl; } } /****************************************************************** * (6) Write a faster insert(key) function for the binomial queue. * In order to achieve that you have to modify the merge() function * and make it specific to the merging of one element only. *****************************************************************/ cout << "\nPart 6. Testing fast insert(key) function [5 times]\n"; cout << "Keys will be inserted in line 0\n"; for( int i = 0; i < 5; ++i ){ key = ""; cout << "Enter a key to insert: "; cin >> key; BinomialNode *bn = BQ.insertFast( key, 0 ); HT.insert( key , bn ); cout << "\"" << key << "\" inserted in Binomial Queue at address: " << bn << endl; cout << "\"" << key << "\" found in Hash Table and has pointer: " << HT.find( key ) << endl; // cout << BQ.getCurrentSize( ); // debugging // BQ.printRoots( ); } cout << "\nPart 6a. Checking the improvement of insertFast() function over the original insert() function [3 times]: \n"; for( int i = 0; i < 3; ++i ){ string w3 = ""; cout << "\nEnter the key to check: "; cin >> w3; BQ.setNumberOfComparisonsAndAssignments( 0, 0 ); cout << "insert(\"" << w3 << "\", 10 )\n"; BinomialNode *bn = BQ.insert( w3, 10 ); HT.insert( "w3", bn ); cout << "\t\tNumber of comparisons = " << BQ.getCmps( ) << endl; cout << "\t\tNumber of assignments = " << BQ.getAsmts( ); // BQ.printRoots( ); cout << "\nNow remove it, reset the counters and test in again:\n\n"; BQ.remove( bn ); HT.remove( "w3"); BQ.setNumberOfComparisonsAndAssignments( 0, 0 ); cout << "insertFast(\"" << w3 << "\", 10 )\n"; BinomialNode *bn2 = BQ.insertFast( w3, 10 ); HT.insert( "w3", bn2 ); cout << "\t\tNumber of comparisons = " << BQ.getCmps( ) << endl; cout << "\t\tNumber of assignments = " << BQ.getAsmts( ); // BQ.printRoots( ); } //////////////////////////////////////////////////////////////////////////////// f1.close(); cout << endl << "End of program. Thanks" << endl; }