十字链表c语言实验报告,有向十字链表的操作(C语言)

以下是数据结构中的有向十字链表的操作

rar.gif

文件:

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();

}

//结构体操作层

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值