问题描述:实现两个有序(非递减有序)顺序表A,B合并成一个顺序表,合并结果放在A中。仍然保持递增的顺序。
思路:从后往前,依次确定顺序表A中的数组第lengthA+lengthB-1位到第0位的数据,当前待定位数据的地址用变量i存储。每次都比较A和B的值,将比较大的值存入数组中。同时设置两个标量A,B,分别记录正在进行比较的对应数组的下标。这样的思路可以使得效率很高。不用担心A表未定位的数据会被覆盖。因为我们可以保证从i到i的前四位的下标对应的数据都是被使用过的(或者是空的)。
简单分析一波:
如果B的数据都比A大,则B的所有数据会存到lengthA到lengthA+lengthB-1中。
如果B的数据都比A小,则A的数据会都被存放到链表的后方,前方虽然有A的数据,但A的数据已经被赋值到后方了,这些数据是冗余的,没用的。
如果正常情况,A有数据比B大,B也有数据比A大,假如某次判断时,A值大于B,则就把A的值赋值并当到这个位置上,A的数据的原来那个位置就被空出来了。未使用的+空出来的一定是等于B剩下的元素个数。如果B的值大于A,则直接填到这个待确定数据大小的地址上。此时未使用的+空出来的一定是等于B剩下的元素个数。
bool merge2(LinkList *A, LinkList B)
{
if (A->length + B.length > MAXSIZE)
{
return false;
}
int nowA = A->length - 1;
int nowB = B.length - 1;
int i = A->length + B.length - 1;
while (nowB > 0&&nowA>0)
{
if (B.data[nowB] >= A->data[nowA])//如果B大于A
{
A->data[i] = B.data[nowB];
nowB--;
i--;
}
else
{
A->data[i] = B.data[nowA];
nowA--;
i--;
}
}
while (nowB > 0)
{
A->data[i] = B.data[nowB];
i--;
nowB--;
}
}
我的笨思路,不想解释了,毫无效率可言,大家可以来笑话笑话我。
void merge(LinkList *A, LinkList B)
{
int nowB = 0;
int nowA = 0;
while (nowA < A->length&&nowB < B.length)
{
if (B.data[nowB] <= A->data[nowA])
{
insert(A, B.data[nowB], nowA + 1);
nowA++;
nowB++;
}
else
{
nowA++;
}
}
while (nowB < B.length)//如果B还没有结束
{
insert(A, B.data[nowB], nowA + 1);
nowA++;
nowB++;
}
return;
}
void insert(LinkList *List, int data,int location)
{
if (List->length == MAXSIZE)
{
return;
}
else if (location > List->length + 1||location<1)
{
return;
}
for (int i = List->length - 1; i >= location - 1; i--)
{
List->data[i + 1] = List->data[i];
}
List->data[location - 1] = data;
List->length++;
}