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

📄 prim.cpp

📁 算法分析与设计
💻 CPP
字号:
#include <iostream.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <search.h>

struct vertex
{
	int x,y;
};

struct ArcNode  //定义边表结点
{
	int av;   //邻接点域
	int w;
	ArcNode* next;
};

struct VexNode  //定义头结点
{
	vertex vex;
	ArcNode* first;
	bool flag;
};

struct edge
{
	int beg,end;
	int cost;
};

void Graph(VexNode adj[],int n,int e,int &a)
{
	int c=999999;
	for(int i=0;i<n;i++)
	{
		adj[i].vex.x=rand();
		adj[i].vex.y=rand();
		adj[i].first=NULL;
		adj[i].flag=0;
	}
	for(int j=1;j<n;j++)
	{
		int r=rand()%j;
		ArcNode* s=new ArcNode;
		s->av=j;
		s->next=adj[r].first;
		adj[r].first=s;
		s->w=(int)sqrt(pow(adj[r].vex.x-adj[j].vex.x,2)+pow(adj[r].vex.y-adj[j].vex.y,2));
		
		ArcNode* t=new ArcNode;
		t->av=r;
		t->next=adj[j].first;
		adj[j].first=t;
		t->w=s->w;

		if(s->w<c)
		{
			c=s->w;
			a=s->av;
		}
	}
	int f=e-n+1;
	while(f>0)
	{
		ran:
		int r1=rand()%n;
		int r2=rand()%n;
		while(r1==r2)
		{
			r2=rand()%n;
		}
		ArcNode *p=adj[r1].first;
		while(p!=NULL)
		{
			if(p->av!=r2)  p=p->next;
			else  goto ran;
		}
		if(p==NULL)
		{
			ArcNode* s=new ArcNode;
			s->av=r2;
			s->next=adj[r1].first;
			adj[r1].first=s;
		    s->w=(int)sqrt(pow(adj[r1].vex.x-adj[r2].vex.x,2)+pow(adj[r1].vex.y-adj[r2].vex.y,2));

			ArcNode* t=new ArcNode;
			t->av=r1;
			t->next=adj[r2].first;
			adj[r2].first=t;
			t->w=s->w;

			if(s->w<c)
			{
				c=s->w;
				a=s->av;
			}
		}
		f--;
	}
}

void SIFT_DOWN(edge x[],int k,int m)
{
	edge temp;
	int i=k, j=2*(i+1)-1;                 //置i为要筛的结点,j为i的左孩子
	while(j<=m)                           //筛选还没进行到叶子结点
	{
		if(j<m && x[j].cost>x[j+1].cost) j++;       //比较i的左右孩子,j为较大者
		if(x[i].cost<=x[j].cost) break;              //根结点已经大于左右孩子中的较大者
		else
		{
			temp=x[i];  x[i]=x[j];  x[j]=temp;
			/*temp.beg = x[i].beg;  temp.end = x[i].end;  temp.w = x[i].w;
			x[i].beg = x[j].beg;  x[i].end = x[j].end;  x[i].w = x[j].w; 
			x[j].beg = temp.beg;  x[j].end = temp.end;  x[j].w = temp.w; */     //将根结点与子结点j交换
			i = j; j = 2*(i+1)-1;                           //被筛结点位于原来结点j的位置
		}
	}
}

void Heap(edge x[],int n)                 //堆排序
{
	for(int i = (n-1)/2; i>=0; i--)       //创建堆,从最后一个非终结点至根结点
		SIFT_DOWN(x,i,n);
}

edge DeleteMin(edge x[],int e)
{
	edge u=x[0];
	edge y=x[e];
	e=e-1;
	x[0]=y;
	SIFT_DOWN(x,0,e);
	return u;
}

int compare(const void *a,const void *b)
{
	return ((edge *)a)->beg - ((edge *)b)->beg;
}

int BinSearch(edge x[],int low,int high,int k)
{
	if(low>high) return 0;
	else
	{
		int mid=(low+high)/2;
		if(k<x[mid].beg) return BinSearch(x,low,mid-1,k);
		else if(k>x[mid].beg)  return BinSearch(x,mid+1,high,k);
		else return mid;
	}
}

void prim(VexNode adj[],edge T[],edge C[],int n,int a)
{
	edge min;
	int *N=new int[n];
	for(int i=0;i<n;i++)
	{	
		C[i].cost=999999;
		ArcNode *t=adj[i].first;
		while(t!=NULL)
		{
			C[t->av].beg=t->av;
			t=t->next;
		}
	}
    ArcNode *p=adj[a].first;
	while(p!=NULL)
	{
	    N[p->av]=a;
		C[p->av].cost=p->w;
		C[p->av].beg=p->av;
		p=p->next;
	}
	adj[a].flag=1;
	//cout<<a<<endl;
	for(int j=1;j<n;j++)
	{
		//int h=n-1;
		Heap(C,n-1);
		Del:
		min=DeleteMin(C,n-1);
		//cout<<min.beg<<" "<<min.cost<<endl;
		if(adj[min.beg].flag==0)
		{	
			adj[min.beg].flag=1;
			T[j].beg=N[min.beg];
			T[j].end=min.beg;
			T[j].cost=min.cost;
		}
		else goto Del;
		qsort((void*)C,n,sizeof(edge),compare);
		ArcNode *q=adj[min.beg].first;
		while(q!=NULL)
		{
			if(adj[q->av].flag==0)
			{
				int key=q->av;
				int z;
				z=BinSearch(C,0,n-1,key);
				if(q->w<=C[z].cost)
				{
					N[q->av]=min.beg;
					C[z].cost=q->w;
					C[z].beg=q->av;
				}
			}
			q=q->next;
		}
	}
}

void main()
{
	clock_t t1,t2;
	double t,sum = 0.0,avg;
	int a,b,source=0;
	cout<<"请输入图中顶点的个数:";
	cin>>a;
	cout<<"\n请输入图中边的条数:";
	cin>>b;
	VexNode *V=new VexNode[a];
	edge *Tree=new edge[a];
	edge *Cost=new edge[a];
	for(int j = 0; j<10; j++)
	{
		Graph(V,a,b,source);	
		t1 = clock();
		prim(V,Tree,Cost,a,source);
		t2 = clock();                     
		t = (double)(t2 - t1)/CLOCKS_PER_SEC;
		sum=+t;
		/*for(int i=1;i<a;i++)
		{
		cout<<Tree[i].beg<<","<<Tree[i].end<<endl;
		cout<<Tree[i].cost<<"\n\n";
		}
		cout<<"**************\n";*/
	}
	avg = sum/10.0;
	cout<<"\n\n测试10次,平均耗时为"<<avg<<"s\n\n";
}

⌨️ 快捷键说明

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