⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dijkstra.cpp

📁 基于测地距离不变性的非线性降维算法源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//***************************************************************************// FIBTEST.CPP//// Test program for the F-heap implementation.// Copyright (c) 1996 by John Boyer.// See header file for free usage information.//***************************************************************************#include <math.h>#include "mex.h"extern void _main();#include <stdlib.h>#include <iostream.h>#include <stdio.h>#include <conio.h>#include <ctype.h>#include <memory.h>#include <time.h>#include "fibheap.h"#define _FIBHEAP_CPP//***************************************************************************// This Fibonacci heap implementation is Copyright (c) 1996 by John Boyer.// See the header file for free usage information.//***************************************************************************//***************************************************************************// The classes in this package are designed to allow the package user// to quickly and easily develop applications that require a heap data// structure.  Using amortized analysis, the asymptotically fastest heap// data structure is the Fibonacci heap.  The constants are a little// high so the real speed gain will not be seen until larger data sets// are required, but in most cases, if the data set is small, then the// run-time will be neglible anyway.//// To use this heap class you need do only two things.  First, subclass// the FibHeapNode class to create the class of objects that you'd// like to store in a heap.  Second, create an instance of the FibHeap// class, which can then be used to Insert(), ExtractMin(), etc.,// instances of your FibHeapNode subclass.  Notice that you don't need// to create a subclass of the FibHeap class.//// The application-specific data object that you'd like to store in a heap// will have a key value.  In the class that you derive from FibHeapNode,// you will need to define the key structure then provide assignment (=),// equality (==) and less-than operators and a destructor.  These functions// are declared virtual so that the code in the FibHeap class can compare,// assign and destroy your objects by calling on your code.//// The overloaded operators in your defined class MUST call functions in// the Fibonacci heap node class first.  For assignment, the function// FHN_Assign() should be called before code that deals with the copy of// the key value.  For comparison operators, the function FHN_Cmp() should// appear first.  If it returns 0, then keys can be compared as normal.// The following indicates what the three most common operators must do// based on the return value of FHN_Cmp() //// For ==, if zero returned, then compare keys//	   if non-zero X returned, then return 0// For <,  if zero returned, then compare keys//         if non-zero X returned, then return X<0?1:0// For >,  if zero returned, then compare keys//         if non-zero X returned, then return X>0?1:0   //***************************************************************************#include <stdlib.h>#include <iostream.h>#include <stdio.h>#include <conio.h>#include "fibheap.h"//***************************************************************************//=========================================================// FibHeapNode Constructor//=========================================================//***************************************************************************FibHeapNode::FibHeapNode(){     Left = Right = Parent = Child = NULL;     Degree = Mark = NegInfinityFlag = 0;}//=========================================================// FibHeapNode Destructor//// Body is empty, but declaration is required in order to// force virtual.  This will ensure that FibHeap class// calls derived class destructors.//=========================================================FibHeapNode::~FibHeapNode(){}//=========================================================// FHN_Assign()//// To be used as first step of an assignment operator in a// derived class.  The derived class will handle assignment// of key value, and this function handles copy of the// NegInfinityFlag (which overrides the key value if it is// set).//=========================================================void FibHeapNode::FHN_Assign(FibHeapNode& RHS){     NegInfinityFlag = RHS.NegInfinityFlag;}//=========================================================// FHN_Cmp()//// To be used as the first step of ALL comparators in a// derived class.//// Compares the relative state of the two neg. infinity// flags.  Note that 'this' is the left hand side.  If// LHS neg. infinity is set, then it will be less than (-1)// the RHS unless RHS neg. infinity flag is also set.// Only if function returns 0 should the key comparison// defined in the derived class be performed, e.g.//// For ==, if zero returned, then compare keys//	   if non-zero X returned, then return 0// For <,  if zero returned, then compare keys//         if non-zero X returned, then return X<0?1:0// For >,  if zero returned, then compare keys//         if non-zero X returned, then return X>0?1:0    //=========================================================int  FibHeapNode::FHN_Cmp(FibHeapNode& RHS){     if (NegInfinityFlag)	 return RHS.NegInfinityFlag ? 0 : -1;     return RHS.NegInfinityFlag ? 1 : 0; }//========================================================================// We do, on occasion, compare and assign objects of type FibHeapNode, but// only when the NegInfinityFlag is set.  See for example FibHeap::Delete().//// Also, these functions exemplify what a derived class should do.//========================================================================void FibHeapNode::operator =(FibHeapNode& RHS){     FHN_Assign(RHS);     // Key assignment goes here in derived classes}int  FibHeapNode::operator ==(FibHeapNode& RHS){     if (FHN_Cmp(RHS)) return 0;     // Key compare goes here in derived classes     return 1;}int  FibHeapNode::operator <(FibHeapNode& RHS){int X;     if ((X=FHN_Cmp(RHS)) != 0)	  return X < 0 ? 1 : 0;     // Key compare goes here in derived classes     return 0;}//=========================================================// Print()//=========================================================void FibHeapNode::Print(){     if (NegInfinityFlag)	 cout << "-inf.";}//***************************************************************************//===========================================================================// FibHeap Constructor//===========================================================================//***************************************************************************FibHeap::FibHeap(){     MinRoot = NULL;     NumNodes = NumTrees = NumMarkedNodes = 0;     ClearHeapOwnership();}//===========================================================================// FibHeap Destructor//===========================================================================FibHeap::~FibHeap(){FibHeapNode *Temp;     if (GetHeapOwnership())     {         while (MinRoot != NULL)         {             Temp = ExtractMin();             delete Temp;	 }     }}//===========================================================================// Insert() - O(1) actual; O(2) amortized//// I am using O(2) here to indicate that although Insert() is// constant time, its amortized rating is more costly because some// of the work of inserting is done by other operations such as// ExtractMin(), which is where tree-balancing occurs.//// The child pointer is deliberately not set to NULL because Insert()// is also used internally to help put whole trees onto the root list.//===========================================================================void FibHeap::Insert(FibHeapNode *NewNode){     if (NewNode == NULL) return;// If the heap is currently empty, then new node becomes singleton// circular root list      if (MinRoot == NULL)	 MinRoot = NewNode->Left = NewNode->Right = NewNode;     else     {// Pointers from NewNode set to insert between MinRoot and MinRoot->Right         NewNode->Right = MinRoot->Right;	 NewNode->Left = MinRoot;// Set Pointers to NewNode  	 NewNode->Left->Right = NewNode;         NewNode->Right->Left = NewNode;// The new node becomes new MinRoot if it is less than current MinRoot         if (*NewNode < *MinRoot)	     MinRoot = NewNode;     }// We have one more node in the heap, and it is a tree on the root list     NumNodes++;     NumTrees++;     NewNode->Parent = NULL;}//===========================================================================// Union() - O(1) actual; O(1) amortized//===========================================================================void FibHeap::Union(FibHeap *OtherHeap){FibHeapNode *Min1, *Min2, *Next1, *Next2;     if (OtherHeap == NULL || OtherHeap->MinRoot == NULL) return;// We join the two circular lists by cutting each list between its// min node and the node after the min.  This code just pulls those// nodes into temporary variables so we don't get lost as changes// are made.     Min1 = MinRoot;     Min2 = OtherHeap->MinRoot;     Next1 = Min1->Right;     Next2 = Min2->Right;// To join the two circles, we join the minimum nodes to the next// nodes on the opposite chains.  Conceptually, it looks like the way// two bubbles join to form one larger bubble.  They meet at one point// of contact, then expand out to make the bigger circle.      Min1->Right = Next2;     Next2->Left = Min1;     Min2->Right = Next1;     Next1->Left = Min2;// Choose the new minimum for the heap      if (*Min2 < *Min1)         MinRoot = Min2;// Set the amortized analysis statistics and size of the new heap                        NumNodes += OtherHeap->NumNodes;     NumMarkedNodes += OtherHeap->NumMarkedNodes;     NumTrees += OtherHeap->NumTrees;// Complete the union by setting the other heap to emptiness// then destroying it     OtherHeap->MinRoot  = NULL;     OtherHeap->NumNodes =     OtherHeap->NumTrees =     OtherHeap->NumMarkedNodes = 0;     delete OtherHeap;}//===========================================================================// Minimum - O(1) actual; O(1) amortized//===========================================================================FibHeapNode *FibHeap::Minimum(){     return MinRoot;}//===========================================================================// ExtractMin() - O(n) worst-case actual; O(lg n) amortized//===========================================================================FibHeapNode *FibHeap::ExtractMin(){FibHeapNode *Result;FibHeap *ChildHeap = NULL;// Remove minimum node and set MinRoot to next node     if ((Result = Minimum()) == NULL)          return NULL;     MinRoot = Result->Right;     Result->Right->Left = Result->Left;     Result->Left->Right = Result->Right;     Result->Left = Result->Right = NULL;     NumNodes --;     if (Result->Mark)     {	 NumMarkedNodes --;         Result->Mark = 0;     }     Result->Degree = 0;// Attach child list of Minimum node to the root list of the heap// If there is no child list, then do no work     if (Result->Child == NULL)     {	 if (MinRoot == Result)	     MinRoot = NULL;     }// If MinRoot==Result then there was only one root tree, so the// root list is simply the child list of that node (which is// NULL if this is the last node in the list)     else if (MinRoot == Result)         MinRoot = Result->Child;// If MinRoot is different, then the child list is pushed into a// new temporary heap, which is then merged by Union() onto the// root list of this heap.     else      {         ChildHeap = new FibHeap();         ChildHeap->MinRoot = Result->Child;     }// Complete the disassociation of the Result node from the heap     if (Result->Child != NULL)	 Result->Child->Parent = NULL;     Result->Child = Result->Parent = NULL;// If there was a child list, then we now merge it with the//	rest of the root list     if (ChildHeap)         Union(ChildHeap);// Consolidate heap to find new minimum and do reorganize work     if (MinRoot != NULL)         _Consolidate();// Return the minimum node, which is now disassociated with the heap// It has Left, Right, Parent, Child, Mark and Degree cleared.     return Result;}//===========================================================================// DecreaseKey() - O(lg n) actual; O(1) amortized//// The O(lg n) actual cost stems from the fact that the depth, and// therefore the number of ancestor parents, is bounded by O(lg n).//===========================================================================int  FibHeap::DecreaseKey(FibHeapNode *theNode, FibHeapNode& NewKey){FibHeapNode *theParent;     if (theNode==NULL || *theNode < NewKey)         return NOTOK;     *theNode = NewKey;     theParent = theNode->Parent;     if (theParent != NULL && *theNode < *theParent)     {         _Cut(theNode, theParent);         _CascadingCut(theParent);     }     if (*theNode < *MinRoot)         MinRoot = theNode;     return OK;}//===========================================================================// Delete() - O(lg n) amortized; ExtractMin() dominates//// Notice that if we don't own the heap nodes, then we clear the// NegInfinityFlag on the deleted node.  Presumably, the programmer// will be reusing the node.//===========================================================================int  FibHeap::Delete(FibHeapNode *theNode){FibHeapNode Temp;int Result;     if (theNode == NULL) return NOTOK;     Temp.NegInfinityFlag = 1;     Result = DecreaseKey(theNode, Temp);     if (Result == OK)         if (ExtractMin() == NULL)             Result = NOTOK;     if (Result == OK)     {         if (GetHeapOwnership())	      delete theNode;	 else theNode->NegInfinityFlag = 0;     }              return Result;}//========================================================================// Print()//// Used internally for debugging purposes.  The function prints the key// value for each node along the root list, then it calls itself on each// child list.   //========================================================================void FibHeap::Print(FibHeapNode *Tree, FibHeapNode *theParent){FibHeapNode* Temp = NULL;     if (Tree == NULL) Tree = MinRoot;     Temp = Tree;     do {	if (Temp->Left == NULL)	    mexPrintf( "(Left is NULL)" );	Temp->Print();	if (Temp->Parent != theParent)	    mexPrintf("(Parent is incorrect)" );	if (Temp->Right == NULL)	     mexPrintf( "(Right is NULL)" );	else if (Temp->Right->Left != Temp)	     mexPrintf( "(Error in left link left) ->" );	else mexPrintf( " <-> " );	Temp = Temp->Right;	if (kbhit() && getch() == 27)	{	    cout << "Hit a key to resume or ESC to break\n";	    if (getch() == 27)                break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -