java深度优先.docx
《java深度优先.docx》由会员分享,可在线阅读,更多相关《java深度优先.docx(22页珍藏版)》请在冰豆网上搜索。
![java深度优先.docx](https://file1.bdocx.com/fileroot1/2023-1/25/e275faf7-8399-4b72-b995-6a1a261bb07d/e275faf7-8399-4b72-b995-6a1a261bb07d1.gif)
java深度优先
packagewg;
importjava.awt.BorderLayout;
importjava.awt.Color;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjavax.swing.JButton;
importjavax.swing.JComboBox;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JPanel;
publicclassGraphicextendsJFrameimplementsActionListener{
MyPanelmp=null;
JPaneljp=null;
JButtonadd=null;
JButtonadd1=null;
JButtontra=null;
JButtoncancel=null;
JLabeljl=null;
JComboBoxjList=null;//下拉列表
String[]travel={"判断是否连接图","查看拓扑排序","判断是否有环","判断是否双向连通的"};
JLabeljlb=null;//装饰标签
publicGraphic(){
mp=newMyPanel();
jl=newJLabel("此处显示结果:
");
jList=newJComboBox(travel);
//jList.addItemListener(this);
add=newJButton("加节点");
add.addActionListener(this);
add.setActionCommand("a");
add1=newJButton("加边");
add1.addActionListener(this);
add1.setActionCommand("aa");
jlb=newJLabel("");
tra=newJButton("确认");
tra.addActionListener(this);
tra.setActionCommand("b");
cancel=newJButton("删除节点");
cancel.addActionListener(this);
cancel.setActionCommand("c");
jp=newJPanel();
jp.add(add);
jp.add(add1);
jp.add(cancel);
jp.add(jlb);
//jp.add(jl);
jp.add(jList);
jp.add(tra);
mp.addMouseListener(mp);
mp.addMouseMotionListener(mp);
this.setFocusable(true);
this.add(mp);
this.add(jp,BorderLayout.NORTH);
this.add(jl,BorderLayout.AFTER_LAST_LINE);
this.setSize(600,500);
this.setLocation(350,150);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
publicstaticvoidmain(String[]args){
newGraphic();
}
@Override
publicvoidactionPerformed(ActionEvente){
booleaniscycle=false;
if(e.getActionCommand().equals("a")){//加节点
mp.isTravel=false;
mp.isAdd1=false;
mp.isAdd=true;
}elseif(e.getActionCommand().equals("aa")){//加边
mp.isTravel=false;
mp.isAdd=false;
mp.isAdd1=true;
}elseif(e.getActionCommand().equals("c")){//删除
mp.isTravel=true;
mp.isAdd=false;
mp.isAdd1=false;
mp.delete();
}elseif(e.getActionCommand().equals("b")){//确认
mp.isTravel=true;
for(inti=0;iNodenode=mp.nodes.get(i);
node.isVisit=false;
}
this.update(this.getGraphics());
Strings=jList.getSelectedItem().toString();//得到选项
if(s=="判断是否连接图"){
if(mp.isconnect())jl.setText("此图是连接的");
elsejl.setText("此处显示结果:
此图不是连接的,可分为"+(mp.num+1)+"个子图");
}elseif(s=="查看拓扑排序"){
Stringtemp="";
//mp.Topological_sort[0]=1
mp.Dfs();
for(inti=0;itemp=temp+""+mp.Topological_sort[i];//拓扑排序的节点访问次数
jl.setText("此处显示结果:
拓扑排序为:
"+temp);
}
elseif(s=="判断是否有环"){
iscycle=mp.iscycle();
if(!
iscycle)jl.setText("此处显示结果:
这个图没有环的");
}
elseif(s=="判断是否双向连通的"){
//System.out.print(mp.isbiconnect()+""+mp.flag);
if(mp.isbiconnect())jl.setText("此处显示结果:
这个无向图是双向连通的");
elsejl.setText("此处显示结果:
这个无向图不是双向连通的");
}
for(inti=0;iNodenode=mp.nodes.get(i);
node.isVisit=false;
}
if(iscycle)//判断有环的话环的节点找到并且加亮显示
{
this.update(this.getGraphics());
try{
Thread.sleep(1500);
}catch(InterruptedExceptione1){
//TODOAuto-generatedcatchblock
e1.printStackTrace();
}
jl.setText("此处显示结果:
这个图是有环的,共:
"+mp.flag+"个");
intj=0;
while(mp.cycle[j]!
=10000)//10000是环的最后一个节点表示结束,后面没有节点了
{
mp.nodes.get(mp.cycle[j]).isVisit=true;
this.update(this.getGraphics());
//System.out.print(mp.cycle[j]);
try{
Thread.sleep(1500);
}catch(InterruptedExceptione1){
//TODOAuto-generatedcatchblock
e1.printStackTrace();
}
j++;
}
}
}
}
}
packagewg;
importjava.awt.Color;
importjava.awt.Graphics;
importjava.awt.event.MouseEvent;
importjava.awt.event.MouseListener;
importjava.awt.event.MouseMotionListener;
importjava.util.Vector;
importjavax.swing.JLabel;
importjavax.swing.JPanel;
publicclassMyPanelextendsJPanelimplementsMouseListener,
MouseMotionListener{
intx,y;
intx1,y1;
intwidth=36;
intheight=36;
inttotal=1000;
intX[][]=newint[total][total];//邻接矩阵,判断x方向是否相连
intY[][]=newint[total][total];//邻接矩阵,判断y方向是否相连
intTopological_sort[]=newint[total];
intcycle[]=newint[total];
booleanvisit[][]=newboolean[total][total];//判断结点是否访问过
booleanisOther=false;//画关系时候判断是否找另一个点
booleanisTravel=false;//判断是否正在遍历
Vectornodes=newVector();
Vectorlines=newVector();
Vectorlabel=newVector();
Nodestart=newNode(0,0);
booleanisAdd=false;
booleanisAdd1=false;
booleanisFirst=true;
intxx,yy,ii;
Vectorchoose=newVector();//拖拽时候用,用来把所有与拖拽节点有边的的直线放进来
publicMyPanel(){//初始化
for(inti=0;ifor(intj=0;jX[i][j]=0;
Y[i][j]=0;
visit[i][j]=false;
}
}
}
publicvoidpaint(Graphicsg){//记住这个每一次调用this.repaint()的时候都要自动调用这个函数
super.paint(g);
g.setColor(Color.DARK_GRAY);//将panel的背景设置灰色就是在背景色灰色上画的图
g.fillRect(0,0,600,450);//画一个矩形画布也就是panel
for(inti=0;iNodenode=nodes.get(i);
node.num=i+1;
this.draw(g,node.x,node.y);//在鼠标的当前位置画一个节点,draw是我写的函数
g.setColor(Color.BLUE);
g.drawString(""+(i+1),node.x,node.y);//画上节点的编号,因为数组是从0开始的所以图示从1开始的所以i+1
if(node.isVisit){//如果节点正在访问,则图上红色
g.setColor(Color.RED);//设置话节点的颜色
g.fill3DRect(node.x,node.y,width,height,false);//画节点
}
}
for(inti=0;iLineNodeline=lines.get(i);
this.draw1(g,line.x1,line.y1,line.x,line.y);//从鼠标的起始位置到终止位置画一条直线,这个函数也是我自己定义的
}
if(isAdd){//添加一个新的节点
this.draw(g,x,y);
//
}
if(isAdd1){//添加一条心的直线
if(isOther){//如果这条直线有了其实位置
this.draw1(g,x1,y1,x,y);
}
}
}
publicbooleanisconnect(){//判断是否连接函数
flag=0;
Dfs();
if(num!
=0)//如果一个图里有多个连通分量则不是连接的
returnfalse;
else
returntrue;
}
publicvoiddraw(Graphicsg,intx,inty){//画节点
g.setColor(Color.GREEN);//画节点的颜色
g.draw3DRect(x,y,width,height,false);//这个是系统函数
}
publicvoiddraw1(Graphicsg,intx1,inty1,intx,inty){//画边
g.setColor(Color.ORANGE);//画边的颜色
g.drawLine(x1,y1,x,y);//这个是系统函数
}
@Override
publicvoidmouseClicked(MouseEvente){//监听鼠标单击事件
//TODOAuto-generatedmethodstub
if(isAdd){//如果加节点
Nodenode=newNode(e.getX(),e.getY());
nodes.add(node);
start=nodes.get(0);//初始节点默认赋值为第一个节点
Topological_sort[0]=1;
}elseif(isAdd1){//加边
if(isOther==false){//绘制直线第一个点的话
x1=e.getX();//当前鼠标所在的坐标
y1=e.getY();
for(inti=0;iNodenode=nodes.get(i);
if((x1>=node.x&&x1<=node.x+width)//找到在哪个节点里
&&(y1>=node.y&&y1<=node.y+height)){
x1=node.x+width/2;//将边的两个端点均赋值为节点的中心
y1=node.y+height/2;
break;
}
}
isOther=true;
}else{//绘制直线第二个点
x=e.getX();//当前鼠标所在的坐标
y=e.getY();
for(inti=0;iNodenode=nodes.get(i);
if((x>=node.x&&x<=node.x+width)//找到在哪个节点里
&&(y>=node.y&&y<=node.y+height)){
x=node.x+width/2;
y=node.y+height/2;
break;
}
}
//
LineNodeline=newLineNode(x1,y1,x,y);//新建一条直线,并加入到直线集合中其中参数是两个端点的值
lines.add(line);
X[x][x1]=1;//用于表示两个节点之间有连接,用于后面遍历
X[x1][x]=1;
Y[y][y1]=1;
Y[y1][y]=1;
isOther=false;
}
}
if(e.getClickCount()==2){//双击将该节点颜色变为红色,可以从当前节点开始遍历
x=e.getX();
y=e.getY();
flag=1;
for(inti=0;iNodenode=nodes.get(i);
node.isVisit=false;
if((x>=node.x&&x<=node.x+width)//找到在哪个节点里
&&(y>=node.y&&y<=node.y+height)){
node.isVisit=true;
Graphicsg=this.getGraphics();//这样得到画笔
g.setColor(Color.RED);
g.fill3DRect(node.x,node.y,width,height,false);
start=node;//将初始节点赋值为当前
break;
}
}
this.repaint();
}
}
@Override
publicvoidmouseEntered(MouseEvente){
}
@Override
publicvoidmouseExited(MouseEvente){
//TODOAuto-generatedmethodstub
}
@Override
publicvoidmousePressed(MouseEvente){
//TODOAuto-generatedmethodstub
}
@Override
publicvoidmouseReleased(MouseEvente){
//TODOAuto-generatedmethodstub
this.isFirst=true;//设置回真
}
@Override
publicvoidmouseDragged(MouseEvente){//监听拖拽事件//当鼠标在面板里拖动时候自动执行这个函数
//TODOAuto-generatedmethodstub
x=e.getX();
y=e.getY();
if(this.isFirst){//设置这个变量目的是完成一次整个拖拽过程只判断一次在哪个节点里
for(ii=0;iiNodenode=nodes.get(ii);
if((x>=node.x&&x<=node.x+width)//找到在哪个节点里
&&(y>=node.y&&y<=node.y+height)){
xx=x-node.x;//把当前间距分别算出来
yy=y-node.y;
choose.clear();//每一次判断节点的时候要新清空
for(intjj=0;jjLineNodel=lines.get(jj);
if((node.x+width/2)==l.x1
&&(node.y+height/2)==l.y1){
Choosec=newChoose(jj,false);//如果该点是直线第一个定的点即为x1,y1,则为假
choose.add(c);
intx4=l.x;//这个表示直线的两个端点
inty4=l.y;
intx5=l.x1;
inty5=l.y1;
X[x4][x5]=0;//重新刷新连接关系
X[x5][x4]=0;
Y[y4][y5]=0;
Y[y5][y4]=0;
}
if((node.x+width/2)==l.x
&&(node.y+height/2)==l.y){//如果是第二个点
Choosec=newChoose(jj,true);
choose.add(c);
intx4=l.x;
inty4