单链表的合并

分数 5

作者 李卫明

单位 杭州电子科技大学

1.2 编写程序,在第1题(第1题:编写程序,建立2个带头结点单链表,输入若干整数将正整数插入第1个单链表,将负整数插入第2个单链表,插入前和插入后单链表保持递增或相等次序,显示2个单链表,最后销毁。程序不可存在内存泄漏。)基础上合并2个单链表,合并前后单链表保持递增或相等次序,显示合并前后单链表。注意不可存在内存泄漏。。

输入格式:

若干整数。

输出格式:

每个单链表输出占一行,元素间用分隔符分隔;共3行

输入样例:

100 2 3 -2 -8 -6 -9 -10 50 2 -1

输出样例:

2->2->3->50->100
-10->-9->-8->-6->-2->-1
-10->-9->-8->-6->-2->-1->2->2->3->50->100

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

栈限制

8192 KB

C程序如下:

#include<stdio.h>  
#include<stdlib.h>  
  
typedef struct LinkList {  
    int Data;  
    struct LinkList *Next;  
} LinkList, *List;  

List  CreatHead();//创建单链表
void Display(List L);//输出单链表
void Destroy(List L);//销毁单链表
void Sort(List L);//将单链表按从小到大的顺序排列
void Merge(List A,List B,List C);//将A和B合并为C(不创建新的结点)

int main() {
 List firstHead, firstTail,secondHead,secondTail,third;
 firstHead = CreatHead();//创建第一个单链表的头结点
 firstTail = firstHead;//第一个尾巴指针指向第一个单链表的头结点
 secondHead = CreatHead();//创建第二个单链表的头结点
 secondTail = secondHead;//让第二个尾巴指针指向第二个单链表的头结点
    third = CreatHead();//创建第三个单链表的头结点
 int v;
 while (scanf("%d", &v) != EOF) {//scanf成功读取数据时返回EOF,读取失败时返回-1
     if (v > 0) {//当我们在scanf函数中输入CTRL + Z时,结束 scanf 函数,达到控制循环的目的。
         List L = CreatHead();//创建一个新结点
         L->Data = v;//让其数据域赋值为v
         firstTail->Next = L;//尾指针的Next域指向新结点
         firstTail = L;//更新尾指针
     }
     else {
         List L = CreatHead();
         L->Data = v;
         secondTail->Next = L;
         secondTail = L;
     }
 }
    Sort(firstHead);//排序
    Sort(secondHead);
    Display(firstHead);//输出单链表
    Display(secondHead);
    Merge(firstHead,secondHead,third);//合并两个单链表
    Display(third);//输出合并后的单链表
    Destroy(third);//销毁单链表
    Destroy(firstHead);//这里采用创建新结点的方式合并两个单链表,因此最后需要将三个单链表全部销毁
    Destroy(secondHead);
}

  
List CreatHead() {  
    List p = (List)malloc(sizeof(LinkList));  //向内存申请空间
    if (p == NULL) {  
        exit(EXIT_FAILURE); // 分配失败时退出  
    }  
    p->Next = NULL;  //p的Next域赋值为空
    return p;  //返回p指针所指向的地址
}  

void Display(List L) {
    List p = L->Next;  //p指向L的Next域,即第一有效结点
    while (p) {  //若链表不为空
        printf("%d", p->Data);  //输出数据
        p = p->Next;  //p指向下一有效结点
        if (p) printf("->");  //若该结点不为空则输出“->”
    }  //根据题目要求的输出结果
    printf("\n");  //换行
}

void Destroy(List L) {  
    List p = L;  //p指向该单链表的头结点
    while (p->Next) {  //p的下一结点为空时退出循环
        List q = p->Next;  //要删除的结点为头节点的下一个结点,即第一有效结点,记录下来这个结点的地址
        p->Next = q->Next;  //头结点指向要删除结点的下一个结点
        free(q);  //删除该结点
    }//循环结束时只剩头结点
    free(p);//删除头结点
}  

void Sort(List L) {//选择排序
    List pStar, pcur,pMin;
    pStar = L->Next;//pStar指向第一有效结点
    int temp;//临时变量
    for (;pStar != NULL;pStar = pStar->Next) {//外循环
        pMin = pStar;//假设最小为pStar,即每次外循环的第一个结点
        for (pcur = pMin->Next;pcur != NULL; pcur = pcur->Next) {//内循环从pStar的下一个结点开始
            if (pcur->Data < pMin->Data) {
                pMin = pcur;//若找到更小则将其地址赋值给pMin
            }
        }
        if (pStar != pMin) {//若最小值地址与最初假设的不同则进行交换
            temp = pMin->Data;
            pMin->Data = pStar->Data;
            pStar->Data = temp;
        }
    }
}

void Merge(List A, List B, List C) {
    List pTail = C;//尾指针指向C的头结点
     A = A->Next;//指向第一有效结点
 B = B->Next;//指向第一有效结点
    while (A && B) {//若A和B链表都不为空
        if (A->Data < B->Data) {//将更小的值加入新链表中
            List NewNode = CreatHead();
            NewNode->Data = A->Data;
            pTail->Next = NewNode;
            pTail = NewNode;
            A = A->Next;//加入后指针指向下一个结点
        }
        else {
            List NewNode = CreatHead();
            NewNode->Data = B->Data;
            pTail->Next = NewNode;
            pTail = NewNode;
            B = B->Next;
        }
    }
    while (A) {//将剩下的数据依次加入到新结点
        List NewNode = CreatHead();
        NewNode->Data = A->Data;
        pTail->Next = NewNode;
        pTail = NewNode;
        A = A->Next;
    }
    while (B) {
        List NewNode = CreatHead();
        NewNode->Data = B->Data;
        pTail->Next = NewNode;
        pTail = NewNode;
        B = B->Next;
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是将两个单链表合并成一个单链表的C++代码: ```c++ #include <iostream> using namespace std; // 定义单链表结构体 struct Node { int val; Node* next; Node(int x) : val(x), next(NULL) {} }; // 将两个单链表合并成一个单链表 Node* merge_list(Node* l1, Node* l2) { Node* head = new Node(-1); // 新链表的头结点 Node* p = head; // 新链表的当前节点 while (l1 != NULL && l2 != NULL) { if (l1->val < l2->val) { p->next = l1; l1 = l1->next; } else { p->next = l2; l2 = l2->next; } p = p->next; } if (l1 != NULL) { p->next = l1; } if (l2 != NULL) { p->next = l2; } return head->next; } // 输出单链表 void print_list(Node* head) { Node* p = head; while (p != NULL) { cout << p->val << " "; p = p->next; } } int main() { Node* l1 = new Node(1); l1->next = new Node(3); l1->next->next = new Node(5); Node* l2 = new Node(2); l2->next = new Node(4); l2->next->next = new Node(6); cout << "合并前的链表1:" << endl; print_list(l1); cout << endl; cout << "合并前的链表2:" << endl; print_list(l2); cout << endl; Node* merged_list = merge_list(l1, l2); cout << "合并后的链表:" << endl; print_list(merged_list); cout << endl; return 0; } ``` 在 `merge_list()` 函数中,首先创建一个新链表的头结点,并用 `p` 指向该节点。然后比较两个链表 `l1` 和 `l2` 中当前节点的值,将较小的节点加入新链表,并将指针移动到下一个节点。直到其中一个链表为空,将剩余的节点加入新链表中。最后返回新链表的头节点。 在 `main()` 函数中,先创建两个单链表 `l1` 和 `l2`,输出合并前的两个链表,调用 `merge_list()` 函数将两个链表合并成一个链表,最后输出合并后的链表。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值