1. 程式人生 > >就地合併2個按值非遞減的單鏈表

就地合併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");
}

 

執行結果: