”光说不练假把式“
先说一下,像数据结构这种理论与实践并重的课程,一定要实际操作一下才能深刻理解它的理论。
用单链表实现集合的 并 运算,声明一个并运算函数
Union(LinkList * ha, LinkList * hb, LinkList * &hc);
之所以是 LinkList * &hc 是因为hc是用来存储并运算以后的元素,是一个新建的单链表,需要进行空间分配,改变他存储的值,所以传递的是他头节点地址的指针。(好吧,说的不是很清楚,希望有大神讲解)
下来定义它,假设你的链表已经排过序;
void Union (LinkList * ha, LinkList * hb, LinkList * &hc)
{
//这里是定义几个指针,pa, pb用来遍历单链表 h a和 h b的,s 用来创建节点的; tc 是用来遍历单链表 hc 的
LinkList * pa = ha -> next, * pb = hb -> next, * s, *tc;
//这里是创建一个头节点 hc
hc = (LinkList *)malloc(sizeof(LinkList));
tc = hc; //tc来遍历 hc
while(pa != NULL && pb != NULL) //如果 pa 和 pb 非空
{
if (pa -> data < pb -> data) //在有序的单链表中 pa 的值小于 pb 的值
{ //复制节点到 hc 中
s = (LinkList *)malloc(sizeof(LinkList)); //s 创建一个节点
s -> data = pa -> data; //把 pa 中的值赋给 s
tc -> next = s; //把 s 连接到 tc 的后面
tc = s; //把 s 的地址赋给 tc 继续遍历
pa = pa -> next; //pa 向后遍历
}
else if (pa -> data > pb -> data) //在有序的单链表中 pa 的值大于 pb 的值
{ //下面的方式和上面的一样
s = (LinkList *)malloc(sizeof(LinkList));
s -> data = pb -> data;
tc -> next = s;
tc = s;
pb = pb -> next;
}
else //这里就是在有序的单链表中 pa 的值等于 pb 的值
{
s = (LinkList *)malloc(sizeof(LinkList));
s -> data = pa -> data; //pa 和 pb 的值都可以赋给 s
tc -> next = s;
tc = s;
pa = pa -> next; //pa 和 pb 同时向后遍历
pb = pb -> next;
}
}
//如果 ha 空了 hb 没空 前面的(pa != NULL && pb != NULL)是可以短路的,就是说,当 pa 先为空时 条件直接不成立,不再
//判断 pb 是否为空,所以下面要判断 pb 是否为空, 然后把 pb 的地址给 pa;如果 pb 先为空,直接把 pa 的值跟在tc后面就行。
//还有就是之所以有 pa = pb 只是把pa 和 pb 各自先为空的代码用一段代码表示而已,你也可以分为两段。
if (pb != NULL)
pa = pb;
while ( pa != NULL)
{
s = (LinkList *)malloc(sizeof(LinkList));
s -> data = pa -> data;
tc -> next = s;
tc = s;
pa = pa -> next;
}
tc -> next = NULL; //最后记得将 tc 的尾元素的后一位置为NULL;
}
每次开头都有这种LinkList * pa = ha -> next, * pb = hb -> next; 赋值,它就是用来遍历的;
还有,有时候不能清楚理解的话,画个图还是有必要的。
上面的代码来自《数据结构教程上机实验指导(第三版)》,清华大学出版社。闲了翻翻吧。