两个表的自然连接
学习资源来自中国大学MOOC。
问题描述
- 表:m行、n列。假设所有元素为整数。
- 两个表自然连接:
图片来自中国大学MOOC。
代码如下:
#include<stdio.h>
#include<stdlib.h>
#define MaxCol 10//最大列数为10
typedef struct node1//定义数据类型
{
int data[MaxCol];
struct node1 *next;
}DList;
typedef struct node2
{
int Row, Col;//行数和列数
DList *next;
}HList;
void create(HList *&h)//创建链表
{
h = (HList*)malloc(sizeof(HList));//创建头节点
h->next = NULL;
printf("请输入行数和列数:\n");
scanf_s("%d%d", &h->Row, &h->Col);//输入行数和列数
DList *r=NULL, *s;
int i, j;
for (i = 0; i < h->Row; i++)
{
printf("输入第%d行:", i + 1);
s = (DList*)malloc(sizeof(DList));
for (j = 0; j < h->Col; j++)
{
scanf_s("%d", &s->data[j]);//输入数据
}
if (h->next == NULL)//尾插法建立链表
{
h->next = s;
}
else
{
r->next = s;
}
r = s;
}
r->next = NULL;
}
void destroy(HList *&h)//销毁链表
{
DList *p = h->next, *q = p->next;
while (q != NULL)
{
free(p);
p = q;
q = p->next;
}
free(p);
free(h);
}
void display(HList *h)//输出链表
{
int i;
DList *p = h->next;
printf("合并后的表为:\n");
while (p != NULL)
{
for (i = 0; i < h->Col; i++)
{
printf("%4d", p->data[i]);
}
printf("\n");
p = p->next;
}
}
void link(HList *&h1, HList*&h2, HList *&h)//连接两个表
{
h = (HList*)malloc(sizeof(HList));//创建两个新表的头节点
h->next = NULL;
DList *s, *r=NULL,*p=h1->next,*q;
h->Row = 0;//行数置为0
h->Col = h1->Col + h2->Col;//列数为两个表列数的和
int i, j, k;
printf("连接的字段是:");
scanf_s("%d%d", &i, &j);
while (p != NULL)
{
q = h2->next;
while (q != NULL)
{
if (p->data[i - 1] == q->data[j - 1])//字段相同则连接
{
s = (DList*)malloc(sizeof(DList));
for (k = 0; k < h1->Col; k++)//先把第一个表值赋给新表
{
s->data[k] = p->data[k];
}
for (k = 0; k < h2->Col; k++)//再连第二个表
{
s->data[k + h1->Col] = q->data[k];
}
if (h->next == NULL)//尾插法建表
{
h->next = s;
}
else
{
r->next = s;
}
r = s;
h->Row++;
}
q = q->next;
}
p = p->next;
}
r->next = NULL;
}
int main()
{
HList *h1, *h2, *h;
printf("第一个表:\n");
create(h1);//建表
printf("第二个表:\n");
create(h2);
link(h1, h2, h);//连接两个表
display(h);//输出两个表
destroy(h1);//销毁表
destroy(h2);
destroy(h);
system("pause");
}
运行结果:
开始没有进行r指针的初始化,就发生了异常,所以一定要记得进行初始化。