线性表的应用,计算任意两个表简单自然连接过程讨论线性表的应用(参考数据结构教程 李春葆)
2015-09-13 13:46
781 查看
问题: 假设有两个表A和B,分别是m1行、n1列和m2行、n2列,它们简单自然连接结果C=AxB(i=j),其中i表示表A中列号,j表示表B中的列号,C为A和B的笛卡儿积中满足指定连接条件的所有记录组,该连接条件为表A的第i列与表B的第j列相等。
C=AxB(3=1)的计算结果如下
什么是笛卡尔积?
设A,B为集合,用A中元素为第一元素,B中元素为第二元素构成有序对,所有这样的有序对组成的集合叫做A与B的笛卡尔积,记作AxB.
例如,A={a,b}, B={0,1,2},则
A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}
B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}
拿题目当例子就是,不考虑 i=j 就是笛卡尔积
也就是C=AxB={ (1,2,3,3,5),(1,2,3,1,6),(1,2,3,3,4),(2,3,3,3,5),(2,3,3,1,6),(2,3,3,3,4),(1,1,1,3,5),(1,1,1,1,6),(1,1,1,3,4)
}
加上条件 第3列的数要等于B表第1列(也就是C表的第4列)相等就是问题所需。
C=AxB(3=1)的计算结果如下
什么是笛卡尔积?
设A,B为集合,用A中元素为第一元素,B中元素为第二元素构成有序对,所有这样的有序对组成的集合叫做A与B的笛卡尔积,记作AxB.
例如,A={a,b}, B={0,1,2},则
A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}
B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}
拿题目当例子就是,不考虑 i=j 就是笛卡尔积
也就是C=AxB={ (1,2,3,3,5),(1,2,3,1,6),(1,2,3,3,4),(2,3,3,3,5),(2,3,3,1,6),(2,3,3,3,4),(1,1,1,3,5),(1,1,1,1,6),(1,1,1,3,4)
}
加上条件 第3列的数要等于B表第1列(也就是C表的第4列)相等就是问题所需。
#include<stdio.h> #include<stdlib.h> /************************************************************************/ /* 问题: 假设有两个表A和B,分别是m1行、n1列和m2行、n2列,它们简 * * 单自然连接结果C=AxB(i=j),其中i表示表A中列号,j表示表B中的列号, * * C为A和B的笛卡儿积中满足指定连接条件的所有记录组,该连接条件为表A * * 的第i列与表B的第j列相等。 */ /************************************************************************/ #define M1 3 //A表的行数 #define N1 3 //A表的列数 #define M2 3 //B表的行数 #define N2 2 //B表的列数 #define MaxRow 10 typedef int ElemType; typedef struct Node1 //数据节点结构体,也就是表的一行 { ElemType data[MaxRow]; struct Node1 *next; //指向后继数据节点,也就是当前行的下一行 }DList; typedef struct Node2 //定义头节点类型 { int Row, Col; //表示的表行数和列数 DList *next; //头节点指向的下一个当然就是数据节点了 }HList; /* CreateTable:创建单链表A */ void CreateTableA(HList * &h, ElemType (*array)[N1],int n) { int i = 0; int j = 0; DList *r, *s; // r将作为尾节点,s作为每轮当前插入的节点 r = NULL; h = (HList *)malloc(sizeof(HList)); //头节点 h->Col = N1; //头节点存储表的行数 h->Row = n; //头节点存储表的列数 h->next = NULL; for (i = 0; i < h->Row; ++i) { s = (DList *)malloc(sizeof(DList)); //为临时存储当前插入节点开辟空间 for (j = 0; j < h->Col; ++j) //赋值到s中 { //DL->data[j] = *(*(array+i) + j); s->data[j] = array[i][j]; } //s的数据data赋值完成 if (h->next == NULL) //尾插法插入数据 s h->next = s; else r->next = s; r = s; } r->next = NULL; } /* CreateTable:创建单链表B,只能根据第二维是N2的数组来创建 */ void CreateTableB(HList * &h, ElemType(*array)[N2], int n) { int i = 0; int j = 0; DList *r, *s; r = NULL; h = (HList *)malloc(sizeof(HList)); h->Col = N2; h->Row = n; h->next = NULL; //DList *DL = (DList *)malloc(sizeof(DList)); for (i = 0; i < h->Row; ++i) { s = (DList *)malloc(sizeof(DList)); for (j = 0; j < h->Col; ++j) { //DL->data[j] = *(*(array+i) + j); s->data[j] = array[i][j]; } if (h->next == NULL) h->next = s; else r->next = s; r = s; } r->next = NULL; } /* DistroyTable:销毁表 */ void DistroyTable(HList *&h) { DList *pre = h->next, *p = pre->next; while (p != NULL) //逐个往后销毁节点 { free(pre); pre = p; p = p->next; } free(pre); //销毁最后一个节点 free(h); //销毁头节点 } /* DispList: 输出链表 */ void DispTable(HList *h) { DList *p; int j = 0; p = h->next; while (p != NULL) //节点往后移 { for (j = 0; j < h->Col; ++j) //节点里面数组每个元素逐个打印出来 { printf(" %-5d", p->data[j]); } p = p->next; printf("\n"); } printf("\n\n"); } /* LinkTable:实现两个表简单自然连接 h3作为连接产生的表 */ void LinkTable(HList *h1, HList *h2, HList *&h3,int i1, int i2) { int i; DList *p = h1->next, *q, *s, *r; //p作为表h1往后移动的节点 q作为h2往后移动的节点, s,r是尾插法所需 r = NULL; h3 = (HList *)malloc(sizeof(HList)); //建立头节点 h3->Row = 0; h3->Col = h1->Col + h2->Col; h3->next = NULL; while (p != NULL) { q = h2->next; //这个表达式放在这里是因为q要在h2中循环遍历多次 while (q != NULL) { if (p->data[i1 - 1] == q->data[i2 - 1]) //比较条件,也就是过滤笛卡尔积的条件 { s = (DList *)malloc(sizeof(DList)); //下面就是开始尾插法插入 for (i = 0; i < h1->Col; ++i) //表A的一行中每个元素赋值个表C当前行元素 { s->data[i] = p->data[i]; } for (; i < h3->Col; ++i) //表B元素增加到表C当前行(也就是刚才表A的 { //元素后面) s->data[i] = q->data[i - h1->Col]; } if (h3->next == NULL) //尾插法插入 h3->next = s; else r->next = s; r = s; h3->Row++; } q = q->next; } p = p->next; } r->next = NULL; //最后一个节点的后置节点要设为NULL } int main() { ElemType A[M1][N1] = { //数组形式的表A { 1, 2, 3 }, { 2, 3, 3 }, { 1, 1, 1 } }; ElemType B[M2][N2] = { //数组形式的表B { 3, 5 }, { 1, 6 }, { 3, 4 } }; HList *h_A; //链表形式的表A HList *h_B; //链表形式的表B HList *h_C; //链表形式的表C CreateTableA(h_A, A, M1); //将数组形式表A变为链表形式表A CreateTableB(h_B, B, M2); DispTable(h_A); DispTable(h_B); LinkTable(h_A, h_B, h_C, 3, 1); DispTable(h_C); DistroyTable(h_A); DistroyTable(h_B); DistroyTable(h_C); system("pause"); return 0; }
相关文章推荐
- 陈越、何钦铭《数据结构》第二讲线性结构 笔记
- 【软考视频基础知识】——数据结构
- 任意长度的高精度大整数加法
- 数据结构之数组实现哈希表应用总结篇
- 数据结构与算法(C#版)第二章 C#语言与面向对象技术(下)V1.0
- 数据结构(与算法)可视化
- 算法与数据结构之折半查找(C语言)
- 数据结构之——交换排序
- 线性表--顺序存储结构
- 为新书《算法——隐匿在数据结构背后的原理》一书而作的序言
- 数据结构之---C语言实现连式多项式
- 莫队算法 sqrt(n)分块思想
- C_数据结构_链表的链式实现
- C _数据结构 _线性表的顺序存储
- 数据结构之一元多项式运算操作5-(加,减,乘,化简)
- 数据结构之——插入排序
- 不使用额外的数据结构,逆序一个栈
- 数据结构面试题1.2.5-在二元树中找出和为某一值的所有路径
- C++ 数据结构1
- 数据结构