今天做题的时候,看到了这样一个常见的合并有序表的算法(已经不是第一次看到),所以现在花点时间来细讲一下。
那么请静下心来,先来看看这个有点绕的程序。
void MergeList_L(LinkList LA, LinkList LB, LinkList& LC)
//已知单链表LA和LB的元素按值非递减排列
//归并LA和LB得到新的单链表LC,LC的元素也按值非递减排列。
{
/********** Begin *********/
LL_Initiate(LC);//初始化
LinkList p(LA->next);
LinkList q(LB->next);
LinkList r(LC);
while (p&&q)//将共有的长度排序
{
LinkList node(new LNode);
node->next = nullptr;
r->next = node;//指向新节点
if (p->data<=q->data)
{
node->data = p->data;
p = p->next;
}
else
{
node->data = q->data;
q = q->next;
}
r = r->next;//指向最后节点
}
if (!q)//LB(p)多出了
{
while (p)
{
LinkList node(new LNode);
r->next = node;
node->data = p->data;
node->next = nullptr;
p = p->next;
r = r->next;
}
}
else
{
while (q)
{
LinkList node(new LNode);
r->next = node;
node->data = q->data;
node->next = nullptr;
q = q->next;
r = r->next;
}
}
//排序算法(输入按从小到大顺序而来)
return;
/********** End **********/
}
上面这个程序实现了LA和LB的合并与排序。
我们假设LA和LB的数据存储如下图1:
图1
这个排序算法是这样实现的:先把LA和LB的俩组数据逐个比较,然后把较长链表中剩下的数据依次存入LC单链表中。
1.那么逐个比较是如何实现的呢?
首先,我们先比较LA的第一个数据和LB的第一个数据。显然,2<3,所以我们取数据2作为链表LC的首元结点。然后,我们再比较LA的第二个数据和LB的第一个数据,3=3,所以我们选择LA的数据3作为LC的第二个节点。之后,依次比较,7>3,所以3为LC的第三个节点。7>5,所以5作为LC的第四个节点......如此反复,最后LC的数据顺序为2->3->3->5->6->7->8->9
2.为什么还需要依次存入剩余数据?
因为逐个比较到9就结束了,而LB中还剩下数据10。所以我们还需要存入剩余数据。
3.如果直接存入剩余数据,那么排序的顺序不会被打乱🐴?
这其实值得思考,毕竟剩余数据没有经过比较,没有经过比较,顺序就不一定为题目要求的升序。所以,为了解决这个问题,我们通过输入时手动升序来解决这个问题。其实,你可以看到图1中,LA和LB的数据排列都是升序,这就是为了避免剩余数据的不排序问题。
另外,顺序线性表的程序实现会比链式线性表简单,如果链式的程序看不懂,可以找顺序表的程序看一看。当然,无论是顺序表还是链式表实现思路都是一样的。
最后,希望我的博客对你有帮助,本博客就先到这里。