列2-1:假设利用两个线性表LA和LB分布表示两个集合A和B(即线性表中的数据元素即为集合中的元素),现要求一个新的集合A=AUB。这就要求对线性表作如下操作,扩大线性表LA,将存在于线性表LB中而不存在于线性表LA中的数据元素插入到线性表LA中去。只要从线性表LB中依次取得每个数据的元素,并依值在线性表LA中进行查访,若存在,则插入之。上述操作过程可用下列算法描述之
void Union(List &La, List Lb) {
// 将所有在线性表Lb中但不在La中的数据元素插入到La中
int La_len,Lb_len,i;
ElemType e;
La_len = ListLength(La); // 求线性表的长度
Lb_len = ListLength(Lb);
for (i=1; i<=Lb_len; i++) {
GetElem(Lb, i, e); // 取Lb中第i个数据元素赋给e
if (!LocateElem(La, e, equal)) // La中不存在和e相同的数据元素
ListInsert(La, ++La_len, e); // 插入
}
} // union
书中给我了伪代码,我们现在来分析下:
1.第一行我们可以知道这个函数叫联合,包含来个参数,一个是线性表La,一个是表Lb,且La是一个引用,这表名La是将会被修改的
2.第三行我们可以知道定义了两个int型变量用于存La和Lb的长度
3.第四行定义了一个ElemType(我猜测这是element和type的组合表示这是一个元素类型,具体是什么类型取决于List容器里面的类型),从下面的代码可知这个变量是为提取Lb中某个数与La中的数进行比较,
4.第五行,第六行可知他调用了一个叫ListLength的函数这函数要传入List。返回List的长度
5.第七行是进行一个循环,这个循环是Lb的长度,从for循环第一个参数可以知道,这个List是从下标1开始,而不是从0开始。
6.第八行是GetElem函数,意思是获取元素,从参数来看,我们知道他获取的是Lb的第i个元素,第三个参数填写的是e,这里我们要思考下如果e是普通类型的参数,那么他根本就无法回调给e(此函数无返回值,只有靠第三个参数回调数据),所以这个ElemType肯定是被typedf为*ElemType。还有一种可能,就是GetElem的第三个参数是一个引用。还是不懂的同学看下面的代码
#include <stdio.h>
typedef struct List
{
int Num = 1;
}*list;
int main()
{
list a;
List b;
b.Num = 10;
a = &b;
return 0;
}
运行结果:
例2-2:已知线性表LA和LB中的元素按值非递减有序排列,现要求将LA和LB归并为一个新的线性表LC,且LC中的数据元素仍按值非递减有序排列。例如,社7.第九行是LocateElem函数,这个用e和La中的每一个元素对比,第三个参数是equal,这个equal是提醒大家这里是比较是否相等,La中没有数和e相等时,if条件成立
8.第十行插入e进La,并且La_Len增加1。
则LA=(3,5,8,11)
LB=(2,6,8,9,11,15,20)
从上述问题要求可知,LC中的数据元素或是LA中的数据元素,或是LB中的数据元素,则只要先设LC为空表,然后将LA或LB中的元素逐个插入LC中即可。为使LC中元素按值非递减有序排列,可设两个指针i和j分别指向LA和LB中某个元素,若设i当前所指的元素为a,j当前所指的元素为b,则当前应插入到LC中的元素为c为LC=(2,3,5,6,8,8,9,11,11,15,20)
显然,指针i和j的初始值均为1,在所指元素插入LC之后,在LA或LB中顺序后移。代码如下:c=a当a<=b时,或者c=b当a>b时
void MergeList(List La, List Lb, List &Lc) {
// 已知线性表La和Lb中的元素按值非递减排列。
// 归并La和Lb得到新的线性表Lc,Lc的元素也按值非递减排列。
int La_len, Lb_len;
ElemType ai, bj;
int i=1, j=1, k=0;
InitList(Lc);
La_len = ListLength(La);
Lb_len = ListLength(Lb);
while ((i <= La_len) && (j <= Lb_len)) { // La和Lb均非空
GetElem(La, i, ai);
GetElem(Lb, j, bj);
if (ai <= bj) {
ListInsert(Lc, ++k, ai);
++i;
} else {
ListInsert(Lc, ++k, bj);
++j;
}
}
while (i <= La_len) {
GetElem(La, i++, ai); ListInsert(Lc, ++k, ai);
}
while (j <= Lb_len) {
GetElem(Lb, j++, bj); ListInsert(Lc, ++k, bj);
}
} // MergeList
书中给我了伪代码,我们现在来分析下:1.函数MergList,意思是混合链,我们可以知道有三个参数La,Lb和&Lc,Lc是要被修改的,所以设为引用
2.InitList是初始化了List,从这里我们可看出,InitList里面那个参数一个是引用
3.第一个while当一个List从头遍历到尾后就结束(剩下的直接加进去后面那两个while就是这个功能)