graph.h
- #pragma once
- #include"UFset.h"
- #define wuqiong -1
- class bian;
- class graph{
- int** juzhen;
- int num;
- string *name;
- public:
- graph(int);
- ~graph();
- void show()const;
- void printEdge(int)const;
- void insert(int,int,int);
- void del(int ,int);
- void DFS(int)const;
- void BMS(int)const;
- bian* prim();
- bian* Kruskal();
- void Dijstra(int);
- void floyd();
- };
- graph::graph(int n):num(n){
- juzhen=new int*[num];
- for(int i=0;i!=num;i++)
- juzhen[i]=new int[num];
- for(int i=0;i<n;i++)
- for(int j=0;j!=num;j++)
- juzhen[i][j]=0;
- name=new string[num];
- cout<<"输入各节点名字"<<endl;
- for( int i=0; i<num;i++ ){
- cin>>name[i];
- for(int j=0;j<i;j++)
- if(name[i]==name[j] ){
- cout<<"重名了,重输!";
- i--;
- break;
- }
- }
- }
- void graph::show()const{
- for( int i=0; i!=num;i++ ){
- for(int j=0;j!=num;j++)
- printf("%6d",juzhen[i][j]);
- cout<<endl;
- }
- cout<<endl;
- }
- void graph::printEdge(int k)const{
- for( int i=0; i!=num;i++ )
- if(juzhen[k][i] )
- cout<<k<<"->"<<i<<" "<<juzhen[k][i];
- cout<<endl;
- }
- void graph::insert(int f,int l,int q){
- if(f>=num||l>=num ){
- cout<<"输入越界"<<endl;
- return ;
- }
- juzhen[f][l]=q;
- juzhen[l][f]=q;
- }
- graph::~graph(){
- int *l=(int*)juzhen;
- delete []l;
- juzhen=0;
- l=0;
- }
- void graph::del(int f ,int l){
- if(f>=num||l>=num ){
- cout<<"输入越界"<<endl;
- return ;
- }
- if(juzhen[f][l]==0){
- cout<<"没有删除意义"<<endl;
- return ;
- }
- juzhen[f][l]=0;
- juzhen[l][f]=0;
- }
- void graph::DFS(int f )const{
- if(f>=num||f<0 ){
- cout<<"输入错误!"<<endl;
- return ;
- }
- bool * mark=new bool[num];
- for(int i=0;i<num;i++)
- mark[i]=false;
- stack<int> zhan;
- zhan.push(f);
- int now=f;
- cout<<name[f]<<" ";
- mark[f]=true;
- for( int i=0;i<num;i++ ){
- if(juzhen[now][i] && mark[i]==false){
- cout<<name[i]<<" ";
- mark[i]=true;
- zhan.push(i);
- now=i;
- i=-1;
- continue;
- }
- if(i==num-1 ){
- if(zhan.size()==0){
- for( i=0;i!=num ;i++ ){
- if(mark[i]==false ){
- now=i;
- cout<<name[i]<<" ";
- mark[i]=true;
- i=0;
- zhan.push(i);
- break;
- }
- }
- if(zhan.size()!=0)
- continue;
- break;
- }
- now=zhan.top();
- zhan.pop();
- i=-1;
- }
- }
- cout<<endl;
- }
- void graph::BMS(int f)const{
- queue<int> duilie;
- int now=f;
- cout<<name[now]<<" ";
- bool *mark=new bool[this->num];
- memset(mark,0,num);
- mark[now]=true;
- while(now!=-1){
- for( int i=0;i< this->num ;i++ ){
- if( juzhen[now][i]!=0 && mark[i]==false ){
- duilie.push(i );
- cout<<name[i]<<" ";
- mark[i]=true;
- }
- }
- if( ! duilie.empty()){
- now=duilie.front();
- duilie.pop();
- }
- else{
- for(int j=0 ; j<num;j++ ){
- if( ! mark[j] ){
- duilie.push(j);
- cout<<name[j]<<" ";
- now=j;
- mark[j]=true;
- break;
- }
- now=-1;
- }
- }
- }
- cout<<endl;
- }
- bian* graph::prim( ){
- bian* minTree=new bian[num-1];
- int treeNum=0;
- vector<bian> next;
- int now=0;
- bool *mark=new bool[num];
- memset(mark,true,num );
- mark[0]=false;
- while(treeNum!=num-1){
- for( int i=0;i<num ;i++ )
- if(juzhen[now][i] && mark[i] )
- next.push_back( bian(now,i,juzhen[now][i]) );
- vector<bian>::iterator p=next.begin();
- for( vector<bian>::iterator bianli=next.begin()+1 ; bianli!=next.end() ;bianli++ ){
- if( p->quanzhi > bianli->quanzhi && mark[bianli->jieshu] ){
- p=bianli;
- now=bianli->jieshu;
- }
- }
- minTree[treeNum++]=*p;
- next.erase(p);
- mark[now]=0;
- }
- return minTree;
- }
- bian* graph::Kruskal(){
- UFset *p;
- p=new UFset(this->num);
- bian* k=new bian[num*(num+1)/2 ];
- int geshu=0;
- for( int i=0; i<num;i++ ){
- for( int j=0; j+i<num;j++ ){
- if(juzhen[ i][j+i ]!=0 )
- k[geshu++]=bian(i,j+i,juzhen[ i][ j+i] );
- }
- }
- qsort(k,geshu,sizeof(bian),aa);
- int h=0;
- bian *re=new bian[num];
- for( int i=0;i<geshu && h<num ;i++ ){
- if( p->isWith(k[i].qishi,k[i].jieshu) )
- continue;
- re[h++]=k[i];
- p->Union(k[i].jieshu,k[i].qishi);
- }
- if(h==num )
- return re;
- else
- return 0;
- }
- //算法关键在于什么时候更新path
- void graph::Dijstra(int qidian ){
- int *path=new int[num];
- int now =qidian;
- int *mark=new int[num];
- int *data=new int[num];
- memset(mark,0,sizeof(int)*num);
- for(int i=0;i<this->num;i++)
- data[i]=wuqiong;
- data[now]=0;
- mark[now]=true;
- for(int i=0;i<this->num;i++)
- path[i]=now;
- for( int ii=0; ii<this->num-1;ii++ ){
- //更新data
- for( int j=0; j<num;j++ ){
- if(this->juzhen[now][j]!=0&&mark[j]==false){
- //什么时候更新path是重点!
- if(data[j]==wuqiong ){
- path[j]=now;
- data[j]=juzhen[now][j];
- }
- if((data[now]+juzhen[now][j])<data[j] ){
- data[j]=data[now]+juzhen[now][j];
- path[j]=now;
- }
- }
- }
- int y=0;
- while(mark[y])y++;
- for( int i=y+1; i<num;i++ )
- if(mark[i]==false && data[i]<data[y] && data[i]!=wuqiong )
- y=i;
- mark[y]=true;
- now=y;
- }
- for(int i=0;i<num;i++){
- int j=i;
- cout<<qidian<<"->"<<i<<" :"<<i<<" ";
- while(j!=qidian ){
- cout<<path[j]<<" ";
- j=path[j];
- }
- cout<<endl;
- }
- }
- void graph::floyd(){
- //初始化
- int** adj;
- adj=new int*[this->num];
- for(int i=0 ;i<num;i++)
- adj[i]=new int[num];
- for(int i=0;i<num;i++)
- for( int j=0;j<num;j++){
- if(juzhen[i][j])
- adj[i][j]=juzhen[i][j];
- else
- adj[i][j]=wuqiong;
- }
- int **path;
- path=new int*[this->num];
- for(int i=0 ;i<num;i++)
- path[i]=new int[num];
- for(int i=0;i<num;i++)
- for( int j=0;j<num;j++)
- path[i][j]=i;
- //算法执行
- for(int i=0;i<num;i++ ){
- for(int j=0;j<num;j++){
- if(i==j)
- continue;
- for( int y=0; y<num;y++){
- if( adj[j][i]!=wuqiong && adj[i][y]!=wuqiong && (adj[j][i]+adj[i][y]<adj[j][y] ||adj[j][y]==wuqiong)){
- path[j][y]=i;
- adj[j][y]=adj[j][i]+adj[i][y];
- }
- }
- }
- }
- for( int i=0; i<num;i++ ){
- cout<<"从"<<i<<"开始"<<endl;
- for(int j=0;j<num;j++){
- int u=j;
- cout<<i<<"->"<<j<<" :"<<" ";
- while( u!=i ){
- cout<<u<<" ";
- u=path[i][u];
- }
- cout<<i<<endl;
- }
- }
- }
bian.h
- #pragma once
- #include<iostream>
- #include<stack>
- #include<string>
- #include<queue>
- #include<cstdlib>
- #include<vector>
- #include<cstdlib>
- #include<algorithm>
- #include<map>
- using namespace std;
- class bian{
- friend class graph;
- int qishi;
- int jieshu;
- int quanzhi;
- public:
- void set(int a,int b,int c){
- this->jieshu=b;
- this->qishi=a;
- this->quanzhi=c;
- }
- bian(int a=0,int b=0,int c=0){
- this->jieshu=b;
- this->qishi=a;
- this->quanzhi=c;
- }
- void show(){
- cout<<qishi<<"->"<<jieshu<<" : "<<quanzhi<<endl;
- }
- bool operator>(bian k){
- return quanzhi-k.quanzhi>0;
- }
- bool operator<(bian k){
- return quanzhi-k.quanzhi<0;
- }
- bool operator==(bian k){
- return quanzhi==k.quanzhi;
- }
- int operator-(bian k ){
- return quanzhi-k.quanzhi;
- }
- };
- int aa(const void *a,const void *b ){
- return *(bian*)a-*(bian*)b;
- }
MaxHeap.h
- #pragma once
- #include<iostream>
- #include<algorithm>
- using namespace std;
- template<class T>
- class MaxHeap{
- T* heapArray;
- int CurrentSize;
- int MaxSize;
- public:
- MaxHeap(T* ,int,int );
- void insert(const T&);
- void del();
- void shift(int );
- void show();
- };
- template<class T>
- MaxHeap<T>::MaxHeap(T* a,int c,int m ){
- this->CurrentSize=c;
- this->MaxSize=m;
- this->heapArray=new T[c];
- for( int i=0;i<c ;i++ )
- this->heapArray[i]=a[i];
- int p=(this->CurrentSize-1)/2;
- while(p!=-1 ){
- this->shift(p--);
- }
- }
- template<class T>
- void MaxHeap<T>::shift(int num ){
- if( num*2+1 >= this->CurrentSize )
- return ;
- int p;
- if( num*2+2 < this->CurrentSize && this->heapArray[num*2+1] < this->heapArray[num*2+2] )
- p=num*2+2;
- else
- p=num*2+1;
- if(this->heapArray[p]>this->heapArray[num] ){
- swap(this->heapArray[p],this->heapArray[num]);
- this->shift(p);
- }
- }
- template<class T>
- void MaxHeap<T>::show(){
- for(int i=0;i<this->CurrentSize;i++)
- cout<<this->heapArray[i]<<" ";
- cout<<endl;
- }
- template<class T>
- void MaxHeap<T>::insert(const T& p){
- if(this->CurrentSize==this->MaxSize)
- return ;
- this->CurrentSize++;
- this->heapArray[this->CurrentSize-1]=p;
- int y=this->CurrentSize-1;
- while(y){
- y=(y-1)/2;
- this->shift(y);
- }
- }
- template<class T>
- void MaxHeap<T>::del(){
- swap(this->heapArray[0],this->heapArray[this->CurrentSize-1]);
- this->CurrentSize--;
- this->shift(0);
- }
UFset.h
- #pragma once
- #include"bian.h"
- class UFset{
- int num;
- int *root;
- int *next;
- int *length;
- public:
- UFset(int);
- bool isWith(int,int);
- void Union(int,int);
- };
- UFset::UFset(int n):num(n){
- this->root=new int[this->num];
- this->next=new int[this->num];
- this->length=new int[this->num];
- memset(this->length,0,num*4);
- for( int i=0; i<num;i++ )
- next[i]=root[i]=i;
- }
- bool UFset::isWith(int a,int b){
- return root[a]==root[b];
- }
- void UFset::Union(int a,int b){
- int l=this->length[a]>this->length[b]?a:b;//目标根->l
- int r=this->root[l];
- int y=next[a];
- next[a]=next[b];
- next[b]=y;
- y=root[l];
- while(root[ next[l] ]!=y ){
- root[ next[l] ]=y;
- l=next[next[l]];
- }
- }
图定义.cpp(测试代码)
- #include"graph.h"
- //此图为无向图
- int main(){
- int num,f,l,p;
- cout<<"输入结点个数"<<endl;
- cin>>num;
- graph k(num);
- cout<<"下面输入节点(按ctrl +Z结束输入)"<<endl<<"f l p"<<endl;
- /* while( cin.good() ){
- cin>>f;
- cin>>l;
- cin>>p;
- if(cin.good())
- k.insert(f,l,p);
- }
- */
- k.insert(0,1,6);
- k.insert(0,2,1);
- k.insert(0,3,5);
- k.insert(1,2,5);
- k.insert(2,3,5);
- k.insert(1,4,3);
- k.insert(2,4,6);
- k.insert(3,5,2);
- k.insert(2,5,4);
- k.insert(4,5,6);
- cout<<"show():"<<endl;
- k.show();
- /* cout<<"del(int,int)"<<endl;
- cin.clear();
- cin>>f>>l;
- k.del(f,l);
- cout<<"show():"<<endl;
- k.show();
- cout<<"k.DFS(0);"<<endl;
- k.DFS(0);
- cout<<"k.BMS(0);"<<endl;
- k.BMS(0);
- cout<<"k.prim()"<<endl;
- bian *op=k.prim();
- for(int i=0;i!=num-1;i++)
- op[i].show();
- cout<<endl;
- op=k.Kruskal();
- if(op)
- for(int i=0;i!=num-1;i++)
- op[i].show();
- else
- cout<<"no in!!!!"<<endl;
- */
- k.Dijstra(0);
- k.floyd();
- }
转载于:https://blog.51cto.com/treap/1089760