mirror of
https://github.com/kangjianwei/Data-Structure.git
synced 2026-02-07 08:52:24 +08:00
♻️ 更新习题2.23的注释,顺便将CFree的代码更新为与其他分支一致
This commit is contained in:
@@ -2,142 +2,188 @@
|
||||
#include "../../../▲课本算法实现/▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
#include "../../../▲课本算法实现/▲02 线性表/04 SinglyLinkedList/SinglyLinkedList.c" //**▲02 线性表**//
|
||||
|
||||
/* 函数原型 */
|
||||
Status Algo_2_23_1(LinkList La, LinkList *Lb, LinkList *Lc);
|
||||
Status Algo_2_23_2(LinkList La, LinkList *Lb, LinkList *Lc);
|
||||
|
||||
/*
|
||||
* 题2.23
|
||||
*
|
||||
* 方法一:将La中的元素插入到Lb中,然后让Lc指向Lb
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc);
|
||||
|
||||
/*
|
||||
* 题2.23
|
||||
*
|
||||
* 方法二:将La和Lb中的元素交替摘下,并将其插入到Lc中
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_2(LinkList La, LinkList Lb, LinkList* Lc);
|
||||
|
||||
// 测试函数,打印元素
|
||||
void PrintElem(LElemType_L e);
|
||||
//测试函数,打印整型
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
LinkList La, Lb, Lc;
|
||||
int i, mark;
|
||||
|
||||
if(InitList_L(&La) && InitList_L(&Lb) && InitList_L(&Lc)) //链表L创建成功
|
||||
LinkList La, Lb, Lc;
|
||||
int i;
|
||||
|
||||
// 0号单元存储的是数组长度
|
||||
int a[] = {10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
|
||||
int b[] = { 8, 2, 4, 6, 8, 10, 12, 14, 16};
|
||||
|
||||
// 准备测试数据
|
||||
InitList_L(&La);
|
||||
InitList_L(&Lb);
|
||||
for(i = 1; i <= a[0]; i++) {
|
||||
ListInsert_L(La, i, a[i]);
|
||||
}
|
||||
for(i = 1; i <= b[0]; i++) {
|
||||
ListInsert_L(Lb, i, b[i]);
|
||||
}
|
||||
printf("La = ");
|
||||
ListTraverse_L(La, PrintElem);
|
||||
printf("\n");
|
||||
printf("Lb = ");
|
||||
ListTraverse_L(Lb, PrintElem);
|
||||
printf("\n");
|
||||
|
||||
// 归并方法测试
|
||||
// Algo_2_23_1(La, Lb, &Lc);
|
||||
Algo_2_23_2(La, Lb, &Lc);
|
||||
|
||||
printf("Lc = ");
|
||||
ListTraverse_L(Lc, PrintElem);
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 题2.23
|
||||
*
|
||||
* 方法一:将La中的元素插入到Lb中,然后让Lc指向Lb
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc)
|
||||
{
|
||||
LinkList p, pb;
|
||||
|
||||
// 初始化Lc
|
||||
InitList_L(Lc);
|
||||
|
||||
// 确保La和Lb存在
|
||||
if(La == NULL || Lb == NULL || Lc == NULL)
|
||||
{
|
||||
for(i=1; i<=5; i++) //创建链表La和Lb
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
pb = Lb;
|
||||
|
||||
// 先遍历La和Lb的共同部分
|
||||
while(La->next != NULL && pb->next != NULL)
|
||||
{
|
||||
// 从La中摘下结点
|
||||
p = La->next;
|
||||
La->next = p->next;
|
||||
|
||||
// 将La中摘下的结点插入到Lb中
|
||||
p->next = pb->next;
|
||||
pb->next = p;
|
||||
|
||||
// 前进到原Lb中下一个结点的位置
|
||||
pb = pb->next->next;
|
||||
}
|
||||
|
||||
// 如果La有剩余,但Lb已遍历到尽头,则需要将La中剩余元素整体链接到Lb的尾部
|
||||
if(pb->next == NULL && La->next != NULL)
|
||||
{
|
||||
pb->next = La->next;
|
||||
La->next = NULL;
|
||||
}
|
||||
|
||||
// 让Lc指向Lb的链表
|
||||
(*Lc)->next = Lb->next;
|
||||
Lb->next = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 题2.23
|
||||
*
|
||||
* 方法二:将La和Lb中的元素交替摘下,并将其插入到Lc中
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_2(LinkList La, LinkList Lb, LinkList* Lc)
|
||||
{
|
||||
LinkList p, pc;
|
||||
int flag; // 指挥当前应当摘下La中的元素还是摘下Lb中的元素
|
||||
|
||||
// 初始化Lc
|
||||
InitList_L(Lc);
|
||||
|
||||
// 确保La和Lb存在
|
||||
if(La == NULL || Lb == NULL || Lc == NULL)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
flag = 0;
|
||||
pc = *Lc;
|
||||
|
||||
// 先遍历La和Lb的共同部分
|
||||
while(La->next!=NULL && Lb->next!=NULL)
|
||||
{
|
||||
// 摘下La中的元素
|
||||
if(flag==0)
|
||||
{
|
||||
// 摘下La中的元素
|
||||
p = La->next;
|
||||
La->next = p->next;
|
||||
|
||||
flag = 1;
|
||||
}
|
||||
// 摘下La中的元素
|
||||
else
|
||||
{
|
||||
ListInsert_L(La, i, 2*i-1);
|
||||
ListInsert_L(Lb, i, 2*i);
|
||||
}
|
||||
}
|
||||
|
||||
printf("验证题 2.23 的方法1输入 1 ,验证题 2.23 的方法2输入 2 :");
|
||||
fflush(stdin);
|
||||
scanf("%d", &mark);
|
||||
printf("\n");
|
||||
|
||||
printf("创建好的链表为:\n");
|
||||
printf("La = ");
|
||||
ListTraverse_L(La, PrintElem);
|
||||
printf("\n");
|
||||
printf("Lb = ");
|
||||
ListTraverse_L(Lb, PrintElem); //输出链表
|
||||
printf("\n\n");
|
||||
|
||||
if(mark==1)
|
||||
p = Lb->next;
|
||||
Lb->next = p->next;
|
||||
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
// 将摘下的元素插入到Lc
|
||||
pc->next = p;
|
||||
pc = pc->next;
|
||||
}
|
||||
|
||||
// 如果La已经遍历到尽头(Lb可能有剩余)
|
||||
if(La->next==NULL)
|
||||
{
|
||||
printf("题 2.23 方法1 验证...\n");
|
||||
Algo_2_23_1(La, &Lb, &Lc);
|
||||
}
|
||||
|
||||
if(mark==2)
|
||||
// 摘下Lb中可能剩余的所有元素
|
||||
p = Lb->next;
|
||||
Lb->next = NULL;
|
||||
pc->next = p;
|
||||
}
|
||||
// 如果La有剩余(Lb一定遍历到尽头了,否则上面的while循环会继续执行)
|
||||
else
|
||||
{
|
||||
printf("题 2.23 方法2 验证...\n");
|
||||
Algo_2_23_2(La, &Lb, &Lc);
|
||||
}
|
||||
|
||||
printf("归并La和Lb为Lc = ");
|
||||
ListTraverse_L(La, PrintElem);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
// 摘下La中剩余的元素
|
||||
p = La->next;
|
||||
La->next = NULL;
|
||||
pc->next = p;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━━━┓
|
||||
┃题2.23:归并两个单链表┃
|
||||
┗━━━━━━━━━━━*/
|
||||
/* 方法一:顺序链接 */
|
||||
Status Algo_2_23_1(LinkList La, LinkList *Lb, LinkList *Lc)
|
||||
// 测试函数,打印元素
|
||||
void PrintElem(LElemType_L e)
|
||||
{
|
||||
LinkList prea, pa, pb;
|
||||
|
||||
if(!La || !(*Lb) || (!La->next && !(*Lb)->next))//La或Lb有一个不存在或两个均为空表时,合并错误
|
||||
return ERROR;
|
||||
|
||||
*Lc = La; //利用A的头结点作C的头结点
|
||||
prea = La;
|
||||
pa = La->next;
|
||||
pb = (*Lb)->next;
|
||||
|
||||
while(pa && pb)
|
||||
{
|
||||
(*Lb)->next = pb->next;
|
||||
prea = pa;
|
||||
pa = pa->next;
|
||||
prea->next = pb;
|
||||
pb->next = pa;
|
||||
prea = pb;
|
||||
pb = (*Lb)->next;
|
||||
}
|
||||
|
||||
if(!pa) //Lb还有剩余
|
||||
prea->next = pb;
|
||||
|
||||
free((*Lb));
|
||||
*Lb = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*━━━━━━━━━━━┓
|
||||
┃题2.23:归并两个单链表┃
|
||||
┗━━━━━━━━━━━*/
|
||||
/* 方法二:交替链接 */
|
||||
Status Algo_2_23_2(LinkList La, LinkList *Lb, LinkList *Lc)
|
||||
{
|
||||
LinkList cur, pa, pb;
|
||||
int i = 0;
|
||||
|
||||
if(!La || !(*Lb) || (!La->next && !(*Lb)->next))//La或Lb有一个不存在或两个均为空表时,合并错误
|
||||
return ERROR;
|
||||
|
||||
*Lc = La; //利用A的头结点作C的头结点
|
||||
cur = (*Lc);
|
||||
pa = La->next;
|
||||
pb = (*Lb)->next;
|
||||
|
||||
while(pa && pb)
|
||||
{
|
||||
i++;
|
||||
if(i%2)
|
||||
{
|
||||
cur->next = pa;
|
||||
cur = pa;
|
||||
pa = pa->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur->next = pb;
|
||||
cur = pb;
|
||||
pb = pb->next;
|
||||
}
|
||||
}
|
||||
|
||||
if(!pa) //La先扫描完
|
||||
cur->next = pb;
|
||||
|
||||
if(!pb) //Lb先扫描完,注意与方法一的区别
|
||||
cur->next = pa;
|
||||
|
||||
free((*Lb));
|
||||
*Lb = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void PrintElem(LElemType_L e)
|
||||
{
|
||||
printf("%d ", e);
|
||||
printf("%2d ", e);
|
||||
}
|
||||
|
||||
@@ -3,18 +3,20 @@
|
||||
#include "LinkList.h" //**▲02 线性表**//
|
||||
|
||||
/*
|
||||
* 题2.23——方法一:将La插入到Lb中
|
||||
* 题2.23
|
||||
*
|
||||
* 合并两个单链表。
|
||||
* 合并完成后,将La和Lb置空,但不销毁。
|
||||
* 方法一:将La中的元素插入到Lb中,然后让Lc指向Lb
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc);
|
||||
|
||||
/*
|
||||
* 题2.23——方法二:将La和Lb中的元素交替插入到Lc中
|
||||
* 题2.23
|
||||
*
|
||||
* 合并两个单链表。
|
||||
* 合并完成后,将La和Lb置空,但不销毁。
|
||||
* 方法二:将La和Lb中的元素交替摘下,并将其插入到Lc中
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_2(LinkList La, LinkList Lb, LinkList* Lc);
|
||||
|
||||
@@ -26,19 +28,25 @@ int main(int argc, char* argv[]) {
|
||||
LinkList La, Lb, Lc;
|
||||
int i;
|
||||
|
||||
// 0号单元存储的是数组长度
|
||||
int a[] = {10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
|
||||
int b[] = {8, 2, 4, 6, 8, 10, 12, 14, 16};
|
||||
|
||||
// 准备测试数据
|
||||
InitList(&La);
|
||||
InitList(&Lb);
|
||||
for(i = 1; i <= 5; i++) {
|
||||
ListInsert(La, i, 2 * i - 1);
|
||||
ListInsert(Lb, i, 2 * i);
|
||||
for(i = 1; i <= a[0]; i++) {
|
||||
ListInsert(La, i, a[i]);
|
||||
}
|
||||
for(i = 1; i <= b[0]; i++) {
|
||||
ListInsert(Lb, i, b[i]);
|
||||
}
|
||||
printf("La = ");
|
||||
ListTraverse(La, PrintElem);
|
||||
printf("Lb = ");
|
||||
ListTraverse(Lb, PrintElem);
|
||||
|
||||
// 合并方法测试
|
||||
// 归并方法测试
|
||||
// Algo_2_23_1(La, Lb, &Lc);
|
||||
Algo_2_23_2(La, Lb, &Lc);
|
||||
|
||||
@@ -49,10 +57,19 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
|
||||
// 合并两个单链表
|
||||
/*
|
||||
* 题2.23
|
||||
*
|
||||
* 方法一:将La中的元素插入到Lb中,然后让Lc指向Lb
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
LinkList p, pb;
|
||||
|
||||
// 初始化Lc
|
||||
InitList(Lc);
|
||||
|
||||
// 确保La和Lb存在
|
||||
if(La == NULL || Lb == NULL || Lc == NULL) {
|
||||
return ERROR;
|
||||
@@ -60,6 +77,7 @@ Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
|
||||
pb = Lb;
|
||||
|
||||
// 先遍历La和Lb的共同部分
|
||||
while(La->next != NULL && pb->next != NULL) {
|
||||
// 从La中摘下结点
|
||||
p = La->next;
|
||||
@@ -73,66 +91,74 @@ Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
pb = pb->next->next;
|
||||
}
|
||||
|
||||
// 如果La有剩余,需要将其全部链接到Lb的尾部
|
||||
// 如果La有剩余,但Lb已遍历到尽头,则需要将La中剩余元素整体链接到Lb的尾部
|
||||
if(pb->next == NULL && La->next != NULL) {
|
||||
pb->next = La->next;
|
||||
La->next = NULL;
|
||||
}
|
||||
|
||||
InitList(Lc);
|
||||
|
||||
// 让Lc指向Lb的链表
|
||||
(*Lc)->next = Lb->next;
|
||||
Lb->next = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 合并两个单链表
|
||||
/*
|
||||
* 题2.23
|
||||
*
|
||||
* 方法二:将La和Lb中的元素交替摘下,并将其插入到Lc中
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_2(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
LinkList p, pc;
|
||||
int flag; // 指挥插入La中的元素还是插入Lb中的元素
|
||||
int flag; // 指挥当前应当摘下La中的元素还是摘下Lb中的元素
|
||||
|
||||
// 初始化Lc
|
||||
InitList(Lc);
|
||||
|
||||
// 确保La和Lb存在
|
||||
if(La == NULL || Lb == NULL || Lc == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
InitList(Lc);
|
||||
|
||||
flag = 0;
|
||||
pc = *Lc;
|
||||
|
||||
while(La->next!=NULL && Lb->next!=NULL){
|
||||
// 需要插入La中的元素
|
||||
if(flag==0) {
|
||||
// 先遍历La和Lb的共同部分
|
||||
while(La->next != NULL && Lb->next != NULL) {
|
||||
// 摘下La中的元素
|
||||
if(flag == 0) {
|
||||
// 摘下La中的元素
|
||||
p = La->next;
|
||||
La->next = p->next;
|
||||
|
||||
flag = 1;
|
||||
} else {
|
||||
|
||||
// 摘下La中的元素
|
||||
} else {
|
||||
p = Lb->next;
|
||||
Lb->next = p->next;
|
||||
|
||||
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
|
||||
// 将摘下的元素插入到Lc
|
||||
pc->next = p;
|
||||
pc = pc->next;
|
||||
}
|
||||
|
||||
// 如果Lb可能有剩余
|
||||
if(La->next==NULL) {
|
||||
// 摘下Lb中的元素
|
||||
// 如果La已经遍历到尽头(Lb可能有剩余)
|
||||
if(La->next == NULL) {
|
||||
// 摘下Lb中可能剩余的所有元素
|
||||
p = Lb->next;
|
||||
Lb->next = NULL;
|
||||
pc->next = p;
|
||||
|
||||
// 如果La有剩余
|
||||
|
||||
// 如果La有剩余(Lb一定遍历到尽头了,否则上面的while循环会继续执行)
|
||||
} else {
|
||||
// 摘下La中的元素
|
||||
// 摘下La中剩余的元素
|
||||
p = La->next;
|
||||
La->next = NULL;
|
||||
pc->next = p;
|
||||
@@ -143,5 +169,5 @@ Status Algo_2_23_2(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
|
||||
// 测试函数,打印元素
|
||||
void PrintElem(ElemType e) {
|
||||
printf("%d ", e);
|
||||
printf("%2d ", e);
|
||||
}
|
||||
|
||||
@@ -3,18 +3,20 @@
|
||||
#include "LinkList.h" //**▲02 线性表**//
|
||||
|
||||
/*
|
||||
* 题2.23——方法一:将La插入到Lb中
|
||||
* 题2.23
|
||||
*
|
||||
* 合并两个单链表。
|
||||
* 合并完成后,将La和Lb置空,但不销毁。
|
||||
* 方法一:将La中的元素插入到Lb中,然后让Lc指向Lb
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc);
|
||||
|
||||
/*
|
||||
* 题2.23——方法二:将La和Lb中的元素交替插入到Lc中
|
||||
* 题2.23
|
||||
*
|
||||
* 合并两个单链表。
|
||||
* 合并完成后,将La和Lb置空,但不销毁。
|
||||
* 方法二:将La和Lb中的元素交替摘下,并将其插入到Lc中
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_2(LinkList La, LinkList Lb, LinkList* Lc);
|
||||
|
||||
@@ -25,123 +27,148 @@ void PrintElem(ElemType e);
|
||||
int main(int argc, char* argv[]) {
|
||||
LinkList La, Lb, Lc;
|
||||
int i;
|
||||
|
||||
|
||||
// 0号单元存储的是数组长度
|
||||
int a[] = {10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
|
||||
int b[] = { 8, 2, 4, 6, 8, 10, 12, 14, 16};
|
||||
|
||||
// 准备测试数据
|
||||
InitList(&La);
|
||||
InitList(&Lb);
|
||||
for(i = 1; i <= 5; i++) {
|
||||
ListInsert(La, i, 2 * i - 1);
|
||||
ListInsert(Lb, i, 2 * i);
|
||||
for(i = 1; i <= a[0]; i++) {
|
||||
ListInsert(La, i, a[i]);
|
||||
}
|
||||
for(i = 1; i <= b[0]; i++) {
|
||||
ListInsert(Lb, i, b[i]);
|
||||
}
|
||||
printf("La = ");
|
||||
ListTraverse(La, PrintElem);
|
||||
printf("Lb = ");
|
||||
ListTraverse(Lb, PrintElem);
|
||||
|
||||
// 合并方法测试
|
||||
|
||||
// 归并方法测试
|
||||
// Algo_2_23_1(La, Lb, &Lc);
|
||||
Algo_2_23_2(La, Lb, &Lc);
|
||||
|
||||
|
||||
printf("Lc = ");
|
||||
ListTraverse(Lc, PrintElem);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// 合并两个单链表
|
||||
/*
|
||||
* 题2.23
|
||||
*
|
||||
* 方法一:将La中的元素插入到Lb中,然后让Lc指向Lb
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
LinkList p, pb;
|
||||
|
||||
|
||||
// 初始化Lc
|
||||
InitList(Lc);
|
||||
|
||||
// 确保La和Lb存在
|
||||
if(La == NULL || Lb == NULL || Lc == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
||||
pb = Lb;
|
||||
|
||||
|
||||
// 先遍历La和Lb的共同部分
|
||||
while(La->next != NULL && pb->next != NULL) {
|
||||
// 从La中摘下结点
|
||||
p = La->next;
|
||||
La->next = p->next;
|
||||
|
||||
|
||||
// 将La中摘下的结点插入到Lb中
|
||||
p->next = pb->next;
|
||||
pb->next = p;
|
||||
|
||||
|
||||
// 前进到原Lb中下一个结点的位置
|
||||
pb = pb->next->next;
|
||||
}
|
||||
|
||||
// 如果La有剩余,需要将其全部链接到Lb的尾部
|
||||
|
||||
// 如果La有剩余,但Lb已遍历到尽头,则需要将La中剩余元素整体链接到Lb的尾部
|
||||
if(pb->next == NULL && La->next != NULL) {
|
||||
pb->next = La->next;
|
||||
La->next = NULL;
|
||||
}
|
||||
|
||||
InitList(Lc);
|
||||
|
||||
|
||||
// 让Lc指向Lb的链表
|
||||
(*Lc)->next = Lb->next;
|
||||
Lb->next = NULL;
|
||||
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 合并两个单链表
|
||||
/*
|
||||
* 题2.23
|
||||
*
|
||||
* 方法二:将La和Lb中的元素交替摘下,并将其插入到Lc中
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_2(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
LinkList p, pc;
|
||||
int flag; // 指挥插入La中的元素还是插入Lb中的元素
|
||||
|
||||
int flag; // 指挥当前应当摘下La中的元素还是摘下Lb中的元素
|
||||
|
||||
// 初始化Lc
|
||||
InitList(Lc);
|
||||
|
||||
// 确保La和Lb存在
|
||||
if(La == NULL || Lb == NULL || Lc == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
InitList(Lc);
|
||||
|
||||
|
||||
flag = 0;
|
||||
pc = *Lc;
|
||||
|
||||
|
||||
// 先遍历La和Lb的共同部分
|
||||
while(La->next!=NULL && Lb->next!=NULL){
|
||||
// 需要插入La中的元素
|
||||
// 摘下La中的元素
|
||||
if(flag==0) {
|
||||
// 摘下La中的元素
|
||||
p = La->next;
|
||||
La->next = p->next;
|
||||
|
||||
|
||||
flag = 1;
|
||||
} else {
|
||||
|
||||
// 摘下La中的元素
|
||||
} else {
|
||||
p = Lb->next;
|
||||
Lb->next = p->next;
|
||||
|
||||
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
|
||||
// 将摘下的元素插入到Lc
|
||||
pc->next = p;
|
||||
pc = pc->next;
|
||||
}
|
||||
|
||||
// 如果Lb可能有剩余
|
||||
|
||||
// 如果La已经遍历到尽头(Lb可能有剩余)
|
||||
if(La->next==NULL) {
|
||||
// 摘下Lb中的元素
|
||||
// 摘下Lb中可能剩余的所有元素
|
||||
p = Lb->next;
|
||||
Lb->next = NULL;
|
||||
pc->next = p;
|
||||
|
||||
// 如果La有剩余
|
||||
|
||||
// 如果La有剩余(Lb一定遍历到尽头了,否则上面的while循环会继续执行)
|
||||
} else {
|
||||
// 摘下La中的元素
|
||||
// 摘下La中剩余的元素
|
||||
p = La->next;
|
||||
La->next = NULL;
|
||||
pc->next = p;
|
||||
}
|
||||
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 测试函数,打印元素
|
||||
void PrintElem(ElemType e) {
|
||||
printf("%d ", e);
|
||||
printf("%2d ", e);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,18 +3,20 @@
|
||||
#include "LinkList.h" //**▲02 线性表**//
|
||||
|
||||
/*
|
||||
* 题2.23——方法一:将La插入到Lb中
|
||||
* 题2.23
|
||||
*
|
||||
* 合并两个单链表。
|
||||
* 合并完成后,将La和Lb置空,但不销毁。
|
||||
* 方法一:将La中的元素插入到Lb中,然后让Lc指向Lb
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc);
|
||||
|
||||
/*
|
||||
* 题2.23——方法二:将La和Lb中的元素交替插入到Lc中
|
||||
* 题2.23
|
||||
*
|
||||
* 合并两个单链表。
|
||||
* 合并完成后,将La和Lb置空,但不销毁。
|
||||
* 方法二:将La和Lb中的元素交替摘下,并将其插入到Lc中
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_2(LinkList La, LinkList Lb, LinkList* Lc);
|
||||
|
||||
@@ -26,19 +28,25 @@ int main(int argc, char* argv[]) {
|
||||
LinkList La, Lb, Lc;
|
||||
int i;
|
||||
|
||||
// 0号单元存储的是数组长度
|
||||
int a[] = {10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
|
||||
int b[] = { 8, 2, 4, 6, 8, 10, 12, 14, 16};
|
||||
|
||||
// 准备测试数据
|
||||
InitList(&La);
|
||||
InitList(&Lb);
|
||||
for(i = 1; i <= 5; i++) {
|
||||
ListInsert(La, i, 2 * i - 1);
|
||||
ListInsert(Lb, i, 2 * i);
|
||||
for(i = 1; i <= a[0]; i++) {
|
||||
ListInsert(La, i, a[i]);
|
||||
}
|
||||
for(i = 1; i <= b[0]; i++) {
|
||||
ListInsert(Lb, i, b[i]);
|
||||
}
|
||||
printf("La = ");
|
||||
ListTraverse(La, PrintElem);
|
||||
printf("Lb = ");
|
||||
ListTraverse(Lb, PrintElem);
|
||||
|
||||
// 合并方法测试
|
||||
// 归并方法测试
|
||||
// Algo_2_23_1(La, Lb, &Lc);
|
||||
Algo_2_23_2(La, Lb, &Lc);
|
||||
|
||||
@@ -49,10 +57,19 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
|
||||
// 合并两个单链表
|
||||
/*
|
||||
* 题2.23
|
||||
*
|
||||
* 方法一:将La中的元素插入到Lb中,然后让Lc指向Lb
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
LinkList p, pb;
|
||||
|
||||
// 初始化Lc
|
||||
InitList(Lc);
|
||||
|
||||
// 确保La和Lb存在
|
||||
if(La == NULL || Lb == NULL || Lc == NULL) {
|
||||
return ERROR;
|
||||
@@ -60,6 +77,7 @@ Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
|
||||
pb = Lb;
|
||||
|
||||
// 先遍历La和Lb的共同部分
|
||||
while(La->next != NULL && pb->next != NULL) {
|
||||
// 从La中摘下结点
|
||||
p = La->next;
|
||||
@@ -73,45 +91,53 @@ Status Algo_2_23_1(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
pb = pb->next->next;
|
||||
}
|
||||
|
||||
// 如果La有剩余,需要将其全部链接到Lb的尾部
|
||||
// 如果La有剩余,但Lb已遍历到尽头,则需要将La中剩余元素整体链接到Lb的尾部
|
||||
if(pb->next == NULL && La->next != NULL) {
|
||||
pb->next = La->next;
|
||||
La->next = NULL;
|
||||
}
|
||||
|
||||
InitList(Lc);
|
||||
|
||||
// 让Lc指向Lb的链表
|
||||
(*Lc)->next = Lb->next;
|
||||
Lb->next = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 合并两个单链表
|
||||
/*
|
||||
* 题2.23
|
||||
*
|
||||
* 方法二:将La和Lb中的元素交替摘下,并将其插入到Lc中
|
||||
*
|
||||
* 交错归并两个单链表,新链表使用原链表的存储空间。
|
||||
*/
|
||||
Status Algo_2_23_2(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
LinkList p, pc;
|
||||
int flag; // 指挥插入La中的元素还是插入Lb中的元素
|
||||
int flag; // 指挥当前应当摘下La中的元素还是摘下Lb中的元素
|
||||
|
||||
// 初始化Lc
|
||||
InitList(Lc);
|
||||
|
||||
// 确保La和Lb存在
|
||||
if(La == NULL || Lb == NULL || Lc == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
InitList(Lc);
|
||||
|
||||
flag = 0;
|
||||
pc = *Lc;
|
||||
|
||||
// 先遍历La和Lb的共同部分
|
||||
while(La->next!=NULL && Lb->next!=NULL){
|
||||
// 需要插入La中的元素
|
||||
// 摘下La中的元素
|
||||
if(flag==0) {
|
||||
// 摘下La中的元素
|
||||
p = La->next;
|
||||
La->next = p->next;
|
||||
|
||||
flag = 1;
|
||||
} else {
|
||||
|
||||
// 摘下La中的元素
|
||||
} else {
|
||||
p = Lb->next;
|
||||
Lb->next = p->next;
|
||||
|
||||
@@ -123,16 +149,16 @@ Status Algo_2_23_2(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
pc = pc->next;
|
||||
}
|
||||
|
||||
// 如果Lb可能有剩余
|
||||
// 如果La已经遍历到尽头(Lb可能有剩余)
|
||||
if(La->next==NULL) {
|
||||
// 摘下Lb中的元素
|
||||
// 摘下Lb中可能剩余的所有元素
|
||||
p = Lb->next;
|
||||
Lb->next = NULL;
|
||||
pc->next = p;
|
||||
|
||||
// 如果La有剩余
|
||||
// 如果La有剩余(Lb一定遍历到尽头了,否则上面的while循环会继续执行)
|
||||
} else {
|
||||
// 摘下La中的元素
|
||||
// 摘下La中剩余的元素
|
||||
p = La->next;
|
||||
La->next = NULL;
|
||||
pc->next = p;
|
||||
@@ -143,5 +169,5 @@ Status Algo_2_23_2(LinkList La, LinkList Lb, LinkList* Lc) {
|
||||
|
||||
// 测试函数,打印元素
|
||||
void PrintElem(ElemType e) {
|
||||
printf("%d ", e);
|
||||
printf("%2d ", e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user