#include <stdio.h>
#include <string.h>
#define OK 1
#define INFINITY 32767
#define MAX_VERTEX_NUM 30
#define MAXINFOLEN 30
#define ERROR 0
#define OVERFLOW -1
#define MAXVERTEXLEN 30
#define FALSE 0
#define TRUE 1
typedef int Status;
typedef enum { DG, DN, UDG, UDN }GraphKind;
typedef int VRType;
typedef int InfoType;
typedef char* VertexType;
//十字链表图结构(适用于有向图)
typedef struct ArcBox
{
int tailvex, headvex;
struct ArcBox* hlink, * tlink;
InfoType* info;
}ArcBox;
typedef struct VexNode
{
VertexType data;
ArcBox* firstin, * firstout;
}VexNode;
typedef struct
{
VexNode xlist[MAX_VERTEX_NUM];
int vexnum, arcnum;
}OLGraph;
Status CreatDG_OL(OLGraph* G)
{
int info;
printf("请依次输入邻接矩阵的节点数,弧数,弧上是否具有额外信息\n");
scanf("%d%d%d", &(G->vexnum), &(G->arcnum), &info);
getchar();
for (int i = 0; i < G->vexnum; i++)
{
printf("请输入第%d个节点的描述\n", i + 1);
G->xlist[i].data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
if (!G->xlist) exit(OVERFLOW);
gets(G->xlist[i].data);
G->xlist[i].firstin = NULL;
G->xlist[i].firstout = NULL;
}
char* ch;
ch = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
if (!ch) exit(OVERFLOW);
int tail = 1000, head = 1000;
for (int i = 0; i < G->arcnum; i++)
{
ArcBox* p;
p = (ArcBox*)malloc(sizeof(ArcBox));
if (!p) exit(OVERFLOW);
printf("请输入弧尾的节点描述\n");
gets(ch);
for (int j = 0; j < G->vexnum; j++)
{
if (strcmp(ch, G->xlist[j].data) == 0)
{
tail = j;
break;
}
}
p->tailvex = tail;
p->tlink = G->xlist[tail].firstout;
G->xlist[tail].firstout = p;
printf("请输入弧头的节点描述\n");
gets(ch);
for (int j = 0; j < G->vexnum; j++)
{
if (strcmp(ch, G->xlist[j].data) == 0)
{
head = j;
break;
}
}
p->headvex = head;
p->hlink = G->xlist[i].firstin;
G->xlist[head].firstin = p;
if (info)
{
printf("请输入弧的描述信息\n");
p->info = (int*)malloc(sizeof(int));
if (!p->info) exit(OVERFLOW);
scanf("%d", p->info);
getchar();
}
else
p->info = NULL;
}
return OK;
}
//孩子兄弟树的数据结构描述
typedef char* TElemType;
typedef struct CSNode
{
TElemType data;
struct CSNode* firstchild, * nextsibling;
}CSNode, * CSTree;
//队列函数
typedef CSTree QElemType;
typedef struct QNode
{
QElemType data;
struct QNode* next;
}QNode, * QueuePtr;
typedef struct
{
QueuePtr front, rear;
}LinkQueue;
Status InitQueue(LinkQueue* Q)
{
Q->front = (QNode*)malloc(sizeof(QNode));
if (!Q->front) exit(OVERFLOW);
Q->rear = Q->front;
return OK;
}
Status EnQueue(LinkQueue* Q, QElemType e)
{
QNode* p;
p = (QNode*)malloc(sizeof(QNode));
if (!p) exit(OVERFLOW);
p->data = e;
Q->rear->next = p;
Q->rear = p;
p->next = NULL;
return OK;
}
Status DeQueue(LinkQueue* Q, QElemType* e)
{
if (Q->front == Q->rear)
return ERROR;
*e = Q->front->next->data;
if (Q->rear == Q->front->next)
Q->rear = Q->front;
QNode* p = Q->front->next;
Q->front->next = p->next;
free(p);
return OK;
}
Status QueueEmpty(LinkQueue Q)
{
if (Q.front == Q.rear)
return TRUE;
else
return FALSE;
}
void PrintQueue(LinkQueue Q)
{
QNode* p = Q.front->next;
if (!p)
printf("空\n");
else
{
while (p)
{
printf("%d\t", p->data + 1);
p = p->next;
}
printf("\n");
}
}
void PrintCSTree_LevelOrder(CSTree T)
{
printf("孩子兄弟树层序输入为\n");
LinkQueue* Q;
Q = (LinkQueue*)malloc(sizeof(LinkQueue));
if (!Q) exit(OVERFLOW);
InitQueue(Q);
EnQueue(Q, T);
QElemType* p;
p = (QElemType*)malloc(sizeof(QElemType));
if (!p) exit(OVERFLOW);
while (!QueueEmpty(*Q))
{
DeQueue(Q, p);
puts((*p)->data);
if ((*p)->firstchild)
EnQueue(Q, (*p)->firstchild);
if ((*p)->nextsibling)
EnQueue(Q, (*p)->nextsibling);
}
}
//栈的数据结构及函数
#define STACK_INIT_SIZE 100
#define STACK_INCREASMENT 10
typedef int SElemType;
typedef struct
{
SElemType* base, * top;
int stacksize;
}SqStack;
Status InitStack(SqStack* S)
{
S->base = (SElemType*)malloc(sizeof(SElemType) * STACK_INIT_SIZE);
if (!S->base) exit(OVERFLOW);
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
}
Status Push(SqStack* S, SElemType e)
{
if (S->top - S->base > S->stacksize)
{
S->base = (SElemType*)realloc(S->base, sizeof(SElemType) * (S->stacksize + STACK_INCREASMENT));
if (!S->base) exit(OVERFLOW);
S->stacksize += STACK_INCREASMENT;
}
*(S->top) = e;
S->top++;
return OK;
}
Status Pop(SqStack* S, SElemType* e)
{
if (S->base == S->top)
return ERROR;
S->top--;
*e = *(S->top);
return OK;
}
Status StackEmpty(SqStack S)
{
if (S.base == S.top)
return TRUE;
else
return FALSE;
}
//求强连通分量辅助数据结构
typedef struct
{
char ch[MAXVERTEXLEN];
int i;
}Help;
//找有向图中的强连通分量(十字链表表示有向图)
int visited[MAX_VERTEX_NUM];
Help finished[MAX_VERTEX_NUM];
void Convert(OLGraph G1, OLGraph* G2)
{
G2->arcnum = G1.arcnum;
G2->vexnum = G1.vexnum;
for (int i = 0; i < G2->vexnum; i++)
{
G2->xlist[i].firstin = NULL;
G2->xlist[i].firstout = NULL;
G2->xlist[i].data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
if (!G2->xlist[i].data) exit(OVERFLOW);
strcpy(G2->xlist[i].data, G1.xlist[i].data);
}
for (int i = 0; i < G2->vexnum; i++)
{
ArcBox* p = G1.xlist[i].firstout;
while (p)
{
ArcBox* q = (ArcBox*)malloc(sizeof(ArcBox));
if (!q) exit(OVERFLOW);
q->headvex = i;
q->tailvex = p->headvex;
q->hlink = G2->xlist[i].firstin;
G2->xlist[i].firstin = q;
q->tlink = G2->xlist[p->headvex].firstout;
G2->xlist[p->headvex].firstout = q;
if (p->info)
{
q->info = (char*)malloc(sizeof(char) * MAXINFOLEN);
if (!q->info) exit(OVERFLOW);
}
p = p->tlink;
}
}
}
void DFSTree_OL(OLGraph G, int m, CSTree T)
{
visited[m] = TRUE;
int first = 1;
ArcBox* r = G.xlist[m].firstout;
CSNode* q;
while (r)
{
if (!visited[r->headvex])
{
CSNode* p = (CSTree)malloc(sizeof(CSNode));
if (!p) exit(OVERFLOW);
p->data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
if (!p->data) exit(OVERFLOW);
strcpy(p->data, G.xlist[r->headvex].data);
if (first == 1)
{
T->firstchild = p;
q = p;
q->nextsibling = NULL;
first = 0;
}
else
{
q->nextsibling = p;
q = p;
q->nextsibling = NULL;
}
DFSTree_OL(G, r->headvex, q);
}
r = r->tlink;
}
if (first == 1)
T->firstchild = NULL;
}
void DFSForest_OL(OLGraph G1, CSTree* T)
{
int first = 1;
for (int i = 0; i < G1.vexnum; i++)
visited[i] = FALSE;
CSNode* q;
for (int i = 0; i < G1.vexnum; i++)
{
if (!visited[i])
{
CSTree p = (CSTree)malloc(sizeof(CSNode));
if (!p) exit(OVERFLOW);
p->data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
if (!p->data) exit(OVERFLOW);
strcpy(p->data, G1.xlist[i].data);
if (first == 1)
{
(*T) = p;
first = 0;
q = p;
(*T)->nextsibling = NULL;
}
else
{
q->nextsibling = p;
q = p;
q->nextsibling = NULL;
}
DFSTree_OL(G1, i, q);
}
}
}
void PostOrderTraverse_CS(CSTree T, SqStack* S)
{
if (T)
{
int i = 0;
CSNode* p = T->firstchild;
CSNode* q = p;
while (q)
{
PostOrderTraverse_CS(q, S);
q = q->nextsibling;
}
Push(S, T->data);
while (strcmp(finished[i].ch, T->data) != 0)
i++;
finished[i].i = 1;
}
}
void DFS_OL(OLGraph G, int m)
{
finished[m].i = 2;
printf("%s\t", G.xlist[m].data);
ArcBox* p = G.xlist[m].firstout;
while (p)
{
if (finished[p->headvex].i == 1)
DFS_OL(G, p->headvex);
p = p->tlink;
}
}
void DFS_OL_Verse(OLGraph G, SqStack* S)
{
char* ch = (char*)malloc(sizeof(char) * MAXINFOLEN);
if (!ch) exit(OVERFLOW);
while (!StackEmpty(*S))
{
Pop(S, &ch);
int i = 0;
while (strcmp(ch, G.xlist[i].data) != 0)
i++;
if (finished[i].i == 1)
{
printf("一个连通分量的所有节点描述为:\n");
DFS_OL(G, i);
printf("\n");
}
}
}
int main()
{
OLGraph* G1;
G1 = (OLGraph*)malloc(sizeof(OLGraph));
if (!G1) exit(OVERFLOW);
CreatDG_OL(G1);
printf("G1的指针指向\n");
for (int i = 0; i < G1->vexnum; i++)
{
ArcBox* p = G1->xlist[i].firstout;
while (p)
{
printf("%s->%s\n", G1->xlist[i].data, G1->xlist[p->headvex].data);
p = p->tlink;
}
}
OLGraph* G2;
G2 = (OLGraph*)malloc(sizeof(OLGraph));
if (!G2) exit(OVERFLOW);
Convert(*G1, G2);
printf("G2的指针指向\n");
for (int i = 0; i < G2->vexnum; i++)
{
ArcBox* p = G2->xlist[i].firstout;
while (p)
{
printf("%s->%s\n", G2->xlist[i].data, G2->xlist[p->headvex].data);
p = p->tlink;
}
}
CSTree T;
DFSForest_OL(*G2, &T);
PrintCSTree_LevelOrder(T);
SqStack S;
InitStack(&S);
CSNode* p = T;
for (int i = 0; i < G2->vexnum; i++)
{
strcpy(finished[i].ch, G2->xlist[i].data);
finished[i].i = 0;
}
while (p)
{
PostOrderTraverse_CS(p, &S);
DFS_OL_Verse(*G1, &S);
p = p->nextsibling;
}
return 0;
}
输入:
13 22 0
V0
V1
V2
V3
V4
V5
V6
V7
V8
V9
V10
V11
V12
V0
V5
V0
V6
V0
V1
V2
V0
V2
V3
V3
V2
V3
V5
V4
V2
V4
V3
V5
V4
V6
V4
V7
V6
V6
V9
V4
V11
V7
V8
V8
V7
V8
V9
V9
V10
V9
V11
V11
V12
V10
V12
V12
V9
原图:
输出: