写这玩意乱写一气。。估计连自己都看不太懂了。。先留在这儿先。。免得程序给弄丢了。。
- #include <iostream>
- #include <string>
- using namespace std;
- struct HeapStruct
- {
- int Capacity;
- int size;
- int *Elements;
- };
- typedef HeapStruct* PriorityQueue;
- PriorityQueue Initialize(int MaxElements)
- {
- PriorityQueue pq=(PriorityQueue)malloc(sizeof(HeapStruct));
- if(pq==NULL)
- {
- cout<<"Bad Memory Allocated!"<<endl;
- exit(1);
- }
- /*if(MaxElements<5)
- {
- cout<<"Too Few!"<<endl;
- return NULL;
- }
- */
- pq->size=0;
- pq->Capacity=MaxElements;
- pq->Elements=(int*)malloc(sizeof(int)*pq->Capacity+1);
- if(pq->Elements==NULL)
- {
- cout<<"Bad Memory Allocated!"<<endl;
- exit(1);
- }
- pq->Elements[0]=-10000;
- return pq;
- }
- void Destroy(PriorityQueue pq)
- {
- free(pq->Elements);
- free(pq);
- }
- bool IsFull(PriorityQueue pq)
- {
- return pq->size==pq->Capacity;
- }
- bool IsEmpty(PriorityQueue pq)
- {
- return pq->size==0;
- }
- void Insert(int data,PriorityQueue pq)
- {
- if(IsFull(pq))
- {
- cout<<"Full!"<<endl;
- return;
- }
- int i;
- for(i=++pq->size;pq->Elements[i/2]>data;i/=2)
- {
- pq->Elements[i]=pq->Elements[i/2];
- }
- pq->Elements[i]=data;
- }
- int DeleteMin(PriorityQueue pq)
- {
- if(IsEmpty(pq))
- {
- cout<<"Empty!"<<endl;
- exit(1);
- }
- int i=1;
- int child;
- int minElement=pq->Elements[1];
- int lastElement=pq->Elements[pq->size--];
- while(i*2<=pq->size)
- {
- child=i*2;
- if(child!=pq->size && pq->Elements[child]>pq->Elements[child+1])
- {
- ++child;
- }
- if(pq->Elements[child]<lastElement)
- {
- pq->Elements[i]=pq->Elements[child];
- }
- else
- {
- break;
- }
- i=child;
- }
- pq->Elements[i]=lastElement;
- return minElement;
- }
- struct VertexNode
- {
- VertexNode * nextVertex;
- string edge;
- int weight;
- VertexNode(string e,int w):weight(w),edge(e){}
- };
- struct Vertex
- {
- string name;
- VertexNode *first;
- Vertex(string n):name(n){first=NULL;}
- };
- typedef Vertex* ab;
- struct Entry;
- struct NonDireGraph
- {
- ab *vertice;
- int verNum;
- NonDireGraph(int vn):verNum(vn)
- {
- vertice=new ab[verNum];
- for(int i=0;i<verNum;i++)
- {
- cout<<"给个名字";
- string tmp;
- cin>>tmp;
- vertice[i]=new Vertex(tmp);
- for(;;)
- {
- cout<<"要加边咩?"<<endl;
- char tmpC;
- cin>>tmpC;
- if(tmpC == 'N')
- {
- break;
- }
- cout<<"给出边名字"<<endl;
- string tmpS;
- cin>>tmpS;
- cout<<"给出权值"<<endl;
- int tmpW;
- cin>>tmpW;
- VertexNode *tmpV=new VertexNode(tmpS,tmpW);
- tmpV->nextVertex=vertice[i]->first;
- vertice[i]->first=tmpV;
- }
- }
- }
- ~NonDireGraph()
- {
- for(int i=0;i<verNum;i++)
- {
- while(vertice[i]->first!=NULL)
- {
- VertexNode *tmp=vertice[i]->first;
- vertice[i]->first=tmp->nextVertex;
- delete tmp;
- }
- delete vertice[i];
- }
- delete [] vertice;
- }
- void AddKnownVertex(const string &name,Entry *e);
- int FindIndexByName(const string &name)
- {
- for(int i=0;i<verNum;i++)
- {
- if(vertice[i]->name==name)
- {
- return i;
- }
- }
- return -1;
- }
- };
- struct Entry
- {
- string name;
- int isVisited;
- int currentWeight;
- string lastVisited;
- Entry(){}
- Entry(string n,bool iv,int cw,string lv):name(n),isVisited(iv),currentWeight(cw),lastVisited(lv){}
- };
- Entry * InitializeEntry(const NonDireGraph &g)
- {
- Entry *retEntry=new Entry[g.verNum];
- for(int i=0;i<g.verNum;i++)
- {
- retEntry[i].name=g.vertice[i]->name;
- retEntry[i].isVisited=0;
- retEntry[i].currentWeight=30000;
- retEntry[i].lastVisited="";
- }
- return retEntry;
- }
- void DisposeEntry(Entry *e)
- {
- delete [] e;
- }
- void NonDireGraph::AddKnownVertex(const string &name,Entry *e)
- {
- int i=FindIndexByName(name);
- for(VertexNode *vn=vertice[i]->first;vn!=NULL;vn=vn->nextVertex)
- {
- for(int j=0;j<verNum;j++)
- {
- if(e[j].isVisited==0 && e[j].name==(vn->edge))
- {
- int previousWeight=0;
- for(int k=0;k<verNum;k++)
- {
- if(e[k].name==name)
- {
- previousWeight=e[k].currentWeight;
- }
- }
- if(e[j].currentWeight>vn->weight+previousWeight)
- {
- e[j].currentWeight=vn->weight+previousWeight;
- e[j].lastVisited=name;
- }
- }
- }
- }
- }
- Entry * Prim(NonDireGraph &g,const string &startName)
- {
- Entry *table=InitializeEntry(g);
- for(int i=0;i<g.verNum;i++)
- {
- if(table[i].name==startName)
- {
- table[i].currentWeight=0;
- table[i].isVisited=1;
- g.AddKnownVertex(startName,table);
- }
- }
- for(;;)
- {
- PriorityQueue pq=Initialize(g.verNum);
- int i;
- for(i=0;i<g.verNum;i++)
- {
- if(!table[i].isVisited)
- {
- Insert(table[i].currentWeight,pq);
- }
- }
- int min=DeleteMin(pq);
- for(i=0;i<g.verNum;i++)
- {
- if(table[i].currentWeight==min)
- {
- table[i].isVisited=1;
- g.AddKnownVertex(table[i].name,table);
- }
- }
- Destroy(pq);
- for(i=0;i<g.verNum;i++)
- {
- if(table[i].isVisited==0)
- {
- continue;
- }
- }
- break;
- }
- return table;
- }
- int main()
- {
- NonDireGraph ndg(7);
- Entry *table=Prim(ndg,"V1");
- for(int i=0;i<ndg.verNum;i++)
- {
- cout<<table[i].name<<' ';
- cout<<table[i].isVisited<<' ';
- cout<<table[i].currentWeight<<' ';
- cout<<table[i].lastVisited<<endl;
- }
- DisposeEntry(table);
- return 0;
- }