Chinaunix首页 | 论坛 | 博客
  • 博客访问: 385702
  • 博文数量: 61
  • 博客积分: 4650
  • 博客等级: 上校
  • 技术积分: 786
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-11 21:07
个人简介

少抱怨,多实干;

文章分类

全部博文(61)

文章存档

2017年(1)

2016年(13)

2015年(1)

2013年(2)

2011年(1)

2010年(3)

2009年(23)

2008年(17)

我的朋友

分类: C/C++

2008-11-24 11:26:52

以下是数据结构中的有向十字链表的操作
  
 
 
 
文件: c_lianbiao.rar
大小: 4KB
下载: 下载
 
//======================
c_struct.h
 
#define MAX_INFO 20
#define MAX_LIST 10
typedef char strInfo[MAX_INFO];
typedef char ErrMsg[MAX_INFO];
//using namespace std;
//参数声名顺序:遵循从出到进的原则
typedef struct ArcBox{//----->弧结点
   int tailvex,headvex;   //弧尾、弧头在表头数组中位置(索引)
   struct ArcBox *tlink,*hlink; //分别指向弧头相同和弧尾相同的的弧的链域的下一个节点
   struct ArcBox *tlink_prior,*hlink_prior;//上一个弧结点
   strInfo info;    //弧信息 弧名
}ArcBox;
typedef struct VexNode{//---->顶点结点
   strInfo data;    //顶点名称
   ArcBox *firstout,*firstin;   //分别指向该顶点的第一条入弧和出弧
}VexNode;
typedef struct OLGraph{//表头列表
   VexNode hlist[MAX_LIST];//表头向量
   int vexnum,arcnum;//有向图的[顶点数]和[弧数]
   int length;//数组的长度
}OLGraph;
 
 
//=========================
c_ctrl.h
 
// c_1.cpp : 定义控制台应用程序的入口点。
#include "stdlib.h"
#include "stdio.h"
#include "dos.h" //clrscr();清屏函数
#include "conio.h"
#include "string.h"
#include "c_struct.h"

//===================firstout对应tlink firstin对应hlink
//********* 返回 c 所在表头的索引,找不到返回 -1 *********//
int LocateVex(OLGraph G,strInfo c)//
{
 int i;
 for(i=0;i {
  if(strcmp(c,G.hlist[i].data)==0)
   return i;
 }
 return -1;
}
//********** 十字链表构造函数,正常返回0,失败返回 -1 **********//
int Inner_InsertArcBox(OLGraph &G,ErrMsg msg=NULL)
{
 ArcBox *box=NULL,*temp=NULL,*prior=NULL;
 strInfo h,t;
 int i,j;
 box=(ArcBox *)malloc(sizeof(ArcBox));// 为弧节点分配空间 
 if(!box)//分置空间失败
 {
  puts("  ---!!!!!!结点分配失败!!!!!!---");
  return -1;//失败返回 -1
 }
 else
 {
  box->hlink=NULL;box->tlink=NULL;
  box->hlink_prior=NULL;box->tlink_prior=NULL;
  printf("请输入[弧尾]和[弧头] <以'空格'或'回车'分隔>:");scanf("%s %s",t,h);getchar();//gets(t);gets(h);
  i=LocateVex(G,t);//查找弧尾位置 tailvex  对应firstout
  while(i<0) //排错
  {
   printf("!!!弧头 %s 不存在,请重新输入:",t);gets(t);
   i=LocateVex(G,t);//查找弧尾位置 tailvex  对应firstout
  }
  j=LocateVex(G,h);//查找弧头位置 headvex  对应firstin
  while(j<0) //排错
  {
   printf("!!!弧尾 %s 不存在,请重新输入:",h);gets(h);
   j=LocateVex(G,h);//查找弧头位置 headvex  对应firstin
  }
  printf("请输入[弧名]:");gets(box->info);
  box->tailvex=i;//指定尾位置 弧尾 它的tlink指向xlist[i]的firstout这一链的最后一个ArcBox -->设置ArcBox的tailvex域
  box->headvex=j;//指定头位置 弧头 它的hlink指向xlist[j]的firstin这一链的最后一个ArcBox -->设置ArcBox的headvex域
  if(G.hlist[i].firstout==NULL)
  {
   G.hlist[i].firstout=box;
  }
  else//----------->设置ArcBox的tlink域
  {
   temp=prior=G.hlist[i].firstout;
   while(temp->tlink!=NULL){ prior=temp;temp=temp->tlink; }//firstout对应tlink firstin对应hlink
   temp->tlink=box;
   box->tlink_prior=prior;
   temp=NULL;prior=NULL;
  }
  if(G.hlist[j].firstin==NULL)
  {
   G.hlist[j].firstin=box;
  }
  else//----------->设置ArcBox的hlink域
  {
   temp=prior=G.hlist[j].firstin;
   while(temp->hlink!=NULL){ prior=temp;temp=temp->hlink; }
   temp->hlink=box;
   box->hlink_prior=prior;
   temp=NULL;prior=NULL;
  }
 }
 G.arcnum+=1;//添一个弧,计数器要加1
 return 0;
}
int CreateDG(OLGraph &G)

 ArcBox *temp=NULL;
 int i,k,vxnum,acnum;
 G.length=MAX_LIST;
 G.arcnum=0;
 G.vexnum=0;
 printf("请输入[顶点数]和[弧数]:");
 //scanf("%d %d",&G.vexnum,&G.arcnum);getchar();
 scanf("%d %d",&vxnum,&acnum);getchar();
 puts("  开构造表头结点......");
 for(i=0;i {
  printf("请输入[顶点信息]:");
  gets(G.hlist[i].data);
  G.hlist[i].firstin=NULL;
  G.hlist[i].firstout=NULL;
  G.vexnum+=1;
 }
 printf("  开始构造链表......\n");
 for(k=0;k { 
  if(Inner_InsertArcBox(G)<0)
  {
   puts("  ---!!!!!!构造链表失败!!!!!!---");
   return -1;
  }
 }
 return 0;//成功返回 0
}
//********** 输入链表信息,只输出 firstout *********//
void PrintOLG_out(OLGraph G)
{
 ArcBox *box;
 int i,j;
 for(i=0;i { 
  j=1;box=NULL;
  printf("\n******结点名称:");puts(G.hlist[i].data);//输出顶点结点名称
  if(G.hlist[i].firstout!=NULL)//如果有链表
  {
   box=G.hlist[i].firstout;//引用ArcBox对象   
   do{ 
    printf("\n--->>第 %2d 个出弧名:%s\n",j,box->info);   
    printf("弧尾:%s ;  ",G.hlist[box->tailvex].data);
    printf("弧头:%s \n\n",G.hlist[box->headvex].data);
    printf("即从 %s 到 %s\n",G.hlist[box->tailvex].data,G.hlist[box->headvex].data);
    box=box->tlink; //firstout对应tlink firstin对应hlink
    j++;
   }while(box!=NULL);   
  }
  else
  {
   puts("该结点没出弧!");
  }
 }
}
//********** 输入链表信息,只输出 firstin *********//
void PrintOLG_in(OLGraph G)
{
 ArcBox *box;
 int i,j;
 for(i=0;i { 
  j=1;box=NULL;
  printf("\n******结点名称:");puts(G.hlist[i].data);//输出顶点结点名称
  if(G.hlist[i].firstin!=NULL)//如果有链表
  {
   box=G.hlist[i].firstin;//引用ArcBox对象   
   do{ 
    printf("\n--->>第 %2d 个入弧名:%s\n",j,box->info);   
    printf("弧尾:%s ;  ",G.hlist[box->tailvex].data);
    printf("弧头:%s \n\n",G.hlist[box->headvex].data);
    printf("即从 %s 到 %s\n",G.hlist[box->tailvex].data,G.hlist[box->headvex].data);
    box=box->hlink; //firstout对应tlink firstin对应hlink
    j++;
   }while(box!=NULL);   
  }
  else
  {
   puts("该结点没入弧!");
  }
 }
}
//********* 查找方法区 **********************************//
//*********查找弧结点,找到返回 ArcBox,否则返回NULL ***//
ArcBox * Find_ArcBox(OLGraph G)
{
 strInfo box_name;
 ArcBox *trg_box=NULL;
 int i;
 printf("请输入要删除弧的名称:");gets(box_name);
 for(i=0;i {
  //开始在firstin引出的链表中找
  if(G.hlist[i].firstin==NULL)
   break;//该节点没有后继链表
  else
  {
   trg_box=G.hlist[i].firstin;
   if(strcmp(trg_box->info,box_name)==0)//第一个节点是目标
   {
    return trg_box;
   }
   while(trg_box->hlink!=NULL)
   {
    trg_box=trg_box->hlink;
    if(strcmp(trg_box->info,box_name)==0)
     return trg_box;
   }
  }//第一轮查找结束  
 }
 for(i=0;i {
  if(G.hlist[i].firstout==NULL)
   break;//该节点没有后继链表
  else
  {
   trg_box=G.hlist[i].firstout;
   if(strcmp(trg_box->info,box_name)==0)//第一个节点是目标
   {
    return trg_box;
   }
   while(trg_box->tlink!=NULL)
   {
    trg_box=trg_box->tlink;
    if(strcmp(trg_box->info,box_name)==0)
     return trg_box;
   }
  }
 }
 return NULL;//找不到就返回NULL
}
//**********查找trg_box的firstin该链的前一个结点**********//
// flag=0,链上的第一个结点即为目标结点,返回NULL
// flag=1,链中的结点,返回ArcBox
// flag=-1,表中不取在,返回NULL
ArcBox * Find_Pre_Firstin_ArcBox(OLGraph G,const ArcBox *trg_box,int & flag)//ArcBox *pre_box=NULL)
{
 ArcBox * pre_box=NULL;
 int head_num=trg_box->headvex;
 if(G.hlist[head_num].firstin==trg_box)
 {
  flag=0;//第一个结点即为要找的结点时返回值为:0
  return NULL;
 }
 pre_box=G.hlist[head_num].firstin;
 do
 {
  if(pre_box->hlink==trg_box)
   break;
  else
   pre_box=pre_box->hlink;
 }while(pre_box!=NULL);
 if(pre_box!=NULL)
 {
  flag=1;//非第一个结点返回: 1
  return pre_box;
 }
 else
 {
  flag=-1;////没找到返回:-1
  return NULL;
 }
}
//**********查找trg_box的firstout该链的前一个结点**********//
// flag=0,链上的第一个结点即为目标结点
// flag=1,链中的结点
// flag=-1,表中不取在
ArcBox * Find_Pre_Firstout_ArcBox(OLGraph G,const ArcBox *trg_box,int & flag)//ArcBox *pre_box=NULL)
{
 ArcBox * pre_box=NULL;
 int tail_num=trg_box->tailvex;
 if(G.hlist[tail_num].firstout==trg_box)
 {
  flag=0;//第一个结点即为要找的结点时返回值为:0
  return NULL;
 }
 pre_box=G.hlist[tail_num].firstout;
 do
 {
  if(pre_box->tlink==trg_box)
   break;
  else
   pre_box=pre_box->tlink;
 }while(pre_box!=NULL);
 if(pre_box!=NULL)
 {
  flag=1;//非第一个结点返回: 1
  return pre_box;
 }
 else
 {
  flag=-1;//没找到返回:-1
  return NULL;
 }
}
void FindBox(OLGraph G,ErrMsg msg)
{
 const ArcBox *box=Find_ArcBox(G);
 if(box==NULL)
 {
  msg="not found";
 }
 else
 {
  printf("节点名称:%s\n",box->info);
  if(box->hlink_prior!=NULL)
   printf("box.hlink_prior.name=%s\n",box->hlink_prior->info);
  if(box->tlink_prior!=NULL)
   printf("box.tlink.prior.info=%s\n",box->tlink_prior->info);
 }
}
//********************************************************//
//********** 插入弧结点,成功返回 0,失败返回 -1 *********//
int InsertArcBox(OLGraph &G)

 if(Inner_InsertArcBox(G)<0)
 {
  puts("---!!!!!!插入失败!!!!!!---");
  return -1;
 }
 return 0;
}
//***********删除弧结点,成功返回1,失败返回 -1 *********//
int DelArcBox(OLGraph &G)
{
 int flag=-1;
 ArcBox *pre_box=NULL;
 ArcBox *del_box=Find_ArcBox(G);
 if(del_box==NULL)
 {
  puts("没有找到该弧,请继续操作....");
  return -1;
 }
 pre_box=Find_Pre_Firstin_ArcBox(G,del_box,flag);
 switch(flag)
 {
 case -1:
  puts("没有找到该弧,请继续操作....");
  return -1;//没有找到要找的弧
 case 0:
  G.hlist[del_box->headvex].firstin=del_box->hlink;
  break;
 case 1:
  if(del_box->hlink==NULL)
   pre_box->hlink=NULL;
  else
   pre_box->hlink=del_box->hlink;
  break;
 default:return -1;
 }
 pre_box=Find_Pre_Firstout_ArcBox(G,del_box,flag);
 switch(flag)
 {
 case -1:return -1;
 case 0:
  G.hlist[del_box->tailvex].firstout=del_box->tlink;
  break;
 case 1:
  if(del_box->tlink==NULL)
   pre_box->tlink=NULL;
  else
   pre_box->tlink=del_box->tlink;
  break;
 default:return -1;
 }
 printf("结点 %s 已被删除!!!\n",del_box->info);
 return 1;
}
//********** 插入顶点结点,成功返回 0,失败返回 -1 *********//
int InsertNode(OLGraph &G,ErrMsg msg=NULL)
{
 int index;
 VexNode *newBase=NULL;
 if(G.vexnum>=G.length)//空间不足
 {
  newBase=(VexNode *)realloc(G.hlist,sizeof(VexNode)*MAX_LIST);
  if(!newBase)
  {
   //G.hlist=newBase;
   G.length+=MAX_LIST;
  }
  else
  {
   msg="分配结点失败";
   return -1;
  }
 }
 else
 {
  index=G.vexnum;
  printf("请输入[顶点信息]:");
  gets(G.hlist[index].data);
  G.hlist[index].firstin=NULL;
  G.hlist[index].firstout=NULL;
  G.vexnum+=1;
 }
 return 0;
}
//********** 删除顶点,成功返回 0,失败返回 -1 *********//
int DelNode(VexNode node)
{
 return 0;
}
int ToFile(OLGraph  &G,ErrMsg msg)
{
 int size,i;
 FILE *fp;
 //if(fp=fopen("olg.cui","a"))//打开文件成功
 //{
 //}
 //else
 i=sizeof(G);
 {
  fp=fopen("olg.cui","w");
  if(!fp)
   return -1;
  size=fwrite(&G,sizeof(G),sizeof(G)-1,fp);
 }
 if(fp)
  fclose(fp);
 return -1;
}
 
//======================
c_menu.h
 
void CtlSrc()
{
 printf("*******************************************************\n");
 printf("       ***********命令选项****************\n");
 printf("           从弧头输出:1\n");
 printf("           从弧尾输出:2\n");
 printf("             插入结点:3\n");
 printf("           删除弧结点:4\n");
 printf("             插入结点:5\n");
 printf("                 查找:6\n");
 printf("                 保存:9\n");
 printf("                 退出:0\n");
 printf("       ***********************************\n");
 printf("*******************************************************\n");
}
 
//========================
c_main.cpp
 
#include "c_ctrl.h"
#include "c_menu.h"
void main()

 char ch;
 ErrMsg errmsg;
 OLGraph G;
 CtlSrc();
 printf("  开始构造表头信息......\n");
 if(CreateDG(G)==0)
  puts("创建成功!");
 else
  puts("创建失败!!!");
 do
 {
  CtlSrc();
  ch=getchar();getchar();
  switch(ch)
  {
   case '1':PrintOLG_in(G);break;
   case '2':PrintOLG_out(G); break;
   case '3':InsertArcBox(G);break;
   case '4':DelArcBox(G);break;
   case '5':InsertNode(G,errmsg);break;
   case '6':FindBox(G,errmsg);break;
   case '9':ToFile(G,errmsg);break;
   default:puts("请输入正确的选项...");
    break;
  }
 }while(ch!='0');
 puts("\n按任意键退出...");
 getchar();
}
//结构体操作层
 
 
阅读(1217) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~