就地合并2个按值非递减的单链表

题目:单链表la,lb按值非递减,归并la和lb,得到新的单链表lc,使得lc也按值非递减,并占用原来的空间(就地)。

算法思想:以一条链为主链,将另一条的各元素插入到这条主链中。

代码:

#include <stdio.h>
#include <malloc.h>

typedef struct node{
    int data;
    struct node *next;
}Node, *Linklist;

int main(void)
{
    int array_la[5] = {4,5,6,7,7};
    int array_lb[2] = {3,4};
    Linklist la = (Linklist)malloc(sizeof(Node));
    la->next = NULL;
    Linklist lb = (Linklist)malloc(sizeof(Node));
    lb->next = NULL;

    Linklist tmp = NULL;
    // 尾插法建立 非降序 链表la
    Linklist r = la;
    for(int i=0;i<5;i++){
//        printf("################\n");
        tmp = (Linklist)malloc(sizeof(Node));
        tmp->data = array_la[i];
//        printf("data = %d\n",tmp->data);

        tmp->next = r->next;
        r->next = tmp;

        r = r->next;
    }
//    printf("************\n");
//    return 0;

//    tmp = la->next;
//    while(tmp){
//        printf("** %d\n",tmp->data);
//        tmp = tmp->next;
//    }
//    return 0;

    // 尾插法建立 非降序 链表lb
    r = lb;
    for(int i=0;i<2;i++){
        tmp = (Linklist)malloc(sizeof(Node));
        tmp->data = array_lb[i];

        tmp->next = r->next;
        r->next = tmp;

        r = r->next;
    }
//    tmp = lb->next;
//    while(tmp){
//        printf("** %d\n",tmp->data);
//        tmp = tmp->next;
//    }
//    return 0;

    // 合并链表la,lb为非降序的链表lc(单纯的指针操作(题目要求占用原来的空间))
    Linklist lc = la;
    Linklist lc_node_pre = lc;
    Linklist lc_node = lc->next;
    Linklist lb_node = lb->next;
    free(lb);
    // 将原lb中的结点插入到lc(原la)中的适当位置
    while(lc_node && lb_node){
//        printf("lc = %d, lb = %d\n",lc_node->data,lb_node->data);
        if(lb_node->data < lc_node->data){
            // 保存下一个链表b中的结点
            Linklist next_lb_node = lb_node->next;
            // 下一个lc_node不变,但下一个lc_node_pre改变
            Linklist next_lc_node_pre = lb_node;

            // 插入lc_node_pre与lc_node之间
            lb_node->next = lc_node;
            lc_node_pre->next = lb_node;

            // 更新lb_node和lc_node_pre
            lb_node = next_lb_node;
            lc_node_pre = next_lc_node_pre;

            // 打印当前的链表c
            tmp = lc->next;
            while(tmp){
                printf("%d ",tmp->data);
                tmp = tmp->next;
            }
            printf("\n");


        }else{
            lc_node_pre = lc_node;
            lc_node = lc_node->next;
        }
    }
    // lc表走完,但lb表没走完,直接把剩下的lb表放在lc的后面
    if(lc_node==NULL){
        lc_node_pre->next = lb_node;
    }

    // 打印合并后的表lc
    printf("lc has been built.\n");
    tmp = lc->next;
    while(tmp){
        printf("%d ",tmp->data);
        tmp = tmp->next;
    }
    printf("\n");

    // 释放链表lc
    Linklist pre = lc;
    Linklist next = lc->next;
    while(next){
      free(pre);

      pre = next;
      next = next->next;
    }
    printf("succeed in free all nodes in lc\n");
}

执行结果:

猜你喜欢

转载自blog.csdn.net/linking_lin/article/details/82496988