南邮数据结构、算法实践周提高题3(图的连通问题和二叉排序树)

本文探讨了如何判断一个图是否连通,并通过深度优先搜索算法实现。此外,还介绍了如何使用后序遍历思想合并两棵二叉排序树的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem 3 Graph and Tree (Difficulty index ★★★★☆)
3-1. A graph is a set of nodes connected in various ways by edges. You can often start at one node, wander along various edges from node to node, and either wind up back where you started, or just visit several of the other nodes in the graph. Some nodes you may not be able to reach at all. The problem to consider is this: how can you tell if a given graph will let you start on any node and visit every other node in the graph, each by some path of edges?
Graphs which allow you to do this are called "connected" graphs.
For this problem, a graph will be defined by a list of edges.
For example, a graph with nodes {a, b, c, d, e} might be defined as having edges: 
(a, b)  (a, c)  (d, e)
This means that you can travel from node a to node b along a single edge, from a to c, and from d to e. But you can't get from a to e, so this graph is not connected.  The order of the nodes makes no difference, because for this problem, the edges of the graph have no direction.  
So, write a program that, given a list of nodes like that above, and a list of edges like above, in text form, determine whether it is possible to get from each node in the graph to every other.
3-2. Merge two binary sorting trees using post-order traversal thought.

3-1
#include<iostream.h>
#define MaxVertexNum 100
bool visited[MaxVertexNum];
static int count=0;
typedef struct{
	char vertex[MaxVertexNum];                //存放结点
	int edges[MaxVertexNum][MaxVertexNum];    //存放边
	int n,e;                                  //n为结点个数,e为边的个数
}MGraph;
void CreateGraph(MGraph &G){
	int i,j,k;
	char x,y;
	cout<<"input the num of vertex and edge:";
	cin>>G.n>>G.e;
	cout<<"input the vertex:";
	for(i=0;i<G.n;i++){
		cin>>G.vertex[i];                         //出入结点
	}
	for(i=0;i<G.n;i++){
		for(j=0;j<G.n;j++){
			G.edges[i][j]=0;                     //初始化边置0
		}
	}
	cout<<"input edges:"<<endl;
	for(k=0;k<G.e;k++){
		cin>>x>>y;
		for(i=0;i<G.n;i++){
			for(j=0;j<G.n;j++){
				if(x==G.vertex[i]&&y==G.vertex[j]){
					G.edges[i][j]=1;                  //输入边的同时,相应的数值置一
					G.edges[j][i]=1;
				}
			}
		}
	}
}
void DFS(MGraph G,int i){                                  //深度优先遍历
	count++;
//	cout<<G.vertex[i]<<" ";
	visited[i]=true;
	for(int j=0;j<G.n;j++){
		if(G.edges[i][j]==1&& !visited[j]){
			DFS(G,j);
		}
	}
}
void DFSTraverseM(MGraph G){
	int i=0;
	for(i=0;i<G.n;i++){
		visited[i]=false;
	}                           //仅仅从第一个结点出发进行遍历
	DFS(G,0);                   //如果能完全遍历,即遍历过的结点数=总结点
}                               //那么图连通,否则不连通。
int main(){
	MGraph G;
	CreateGraph(G);
//	cout<<"BFS:";
	DFSTraverseM(G);
	if(count==G.n){   
		cout<<"connected."<<endl;
	}else{
		cout<<"not connected."<<endl;
	}
	return 0;
}

3-2
#include<iostream.h>
template <class T>
struct BTNode{       //节点类
	T element;        
	BTNode<T> *lchild,*rchild;    //左孩子、右孩子
	BTNode(){
		lchild=rchild=NULL;
	}
	BTNode(T x){
		element=x;
		lchild=rchild=NULL;
	}
};

template <class T>
class BSTree{               //二叉排序树类
	public:	
		BTNode<T> *root;	//根节点
		int sum;
		int num;
		BSTree(){
			root=NULL;
			sum=num=0;
		}		
		void PostOrder(BTNode<T> *,T *arr);         //实现后序遍历
		void Insert(T x);                          //实现插入元素
};
template <class T>
void BSTree<T>::PostOrder(BTNode<T> *bt,T *arr){   //后序遍历函数的具体实现
	if(bt){
		PostOrder(bt->lchild,arr);
		PostOrder(bt->rchild,arr);
		arr[sum++]=bt->element;
	}
}

template <class T>
void BSTree<T>::Insert(T x){                         //插入元素的具体实现函数
	BTNode<T> *p=root,*q=NULL;
	while(p){
	  q=p;
	  if(x<p->element)
		  p=p->lchild;
	  else if(x>p->element)
		  p=p->rchild;
	  else{ 
		  x=p->element;
		  return;
	  }
	}
	num++;
	p=new BTNode<T>(x);
	if(!root)root=p;
	else if(x<q->element)
		q->lchild=p;
	else
		q->rchild=p;
}

int main ()
{
	BSTree<int> root1,root2,root3;
	int i,m1,m2;
	cout<<"input the num of tree1 and tree2:"<<endl;
	cin>>m1>>m2;
	int *a=new int [m1];
	int *b=new int [m2];
	int *c=new int [m1];
	int *d=new int [m2];
	int *e=new int [m1+m2];
	int *f=new int [m1+m2];	
	cout<<"input the tree1:"<<endl;      //生成第一棵二叉排序树
	for(i=0;i<m1;i++){
		cin>>a[i];
		root1.Insert(a[i]);
	}
	cout<<"input the tree2:"<<endl;      //生成第二棵二叉排序树
	for(i=0;i<m2;i++){
		cin>>b[i];
		root2.Insert(b[i]);
	}
	root1.PostOrder(root1.root,c);
	root2.PostOrder(root2.root,d);
	for(i=0;i<root1.num;i++){   	//合并两个后序遍历得到的数组
		e[i]=c[i];
	}
	for(i=root1.num;i<root1.num+root2.num;i++){
		e[i]=d[i-root1.num];
	}	
	for(i=0;i<root1.num+root2.num;i++){      //构建合并后的二叉平衡树
		root3.Insert(e[i]);
	}
	root3.PostOrder(root3.root,f);	
	cout<<"merge tree1 and tree2:"<<endl;
	for(i=0;i<root3.num;i++){
		cout<<f[i]<<" ";
	}	
	cout<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值