数据结构考研--线性表例2-3

//天勤p28,例2-3
//A,B是两条单链表(带表头节点),其中元素递增有序。设计一个算法,将两条链表合并成一条非递减有序的链表
#include "stdio.h"
#include<stdlib.h>
typedef struct Node{    //结构体
    int data;
    Node *next;
}Node;



void init(Node *&p){    //初始化
    p->next = NULL;
}
void listCreate(Node *&p,int n){      //参数:头节点,数据
    Node *q = (Node *)malloc(sizeof(Node));
    //****头插法建立(插入)链表*********(后进先出)
    q->data = n;
    q->next = p->next;
    p->next = q;
    //****************
}
void Traversal(Node *&p){   //遍历
    Node *q = p->next;
    while (q != NULL)
    {
        printf("%d ",q->data);
        q = q->next;
    }
}
void merge(Node *&A,Node *&B,Node *&C){   //每次从两条链表里选一个最小的插入 //由于两条链表都是递增有序的,只要比头就好了
    Node *p = A->next;
    Node *q = B->next;
    C->next = NULL;
    Node *cTail = C;    //指向c的尾部,只有头节点时头就是尾
    // 首先要找到元素,再插入 
    while (p != NULL && q != NULL){
        if (p->data > q->data){   //尾插法将AB链表上的节点插到C中,注意这里是整个节点插入,这样C就不用另外申请空间
            cTail->next = q;  //将q从接入C的尾部
            cTail = q;        //尾指针指向最新的尾部q
            q = q->next;      //q后移
        }else{
            cTail->next = p;
            cTail = p;
            p = p->next;
        }
    }//到最后,若A或B链表还有剩,则直接并入到c尾
    if (p != NULL){
        cTail->next = p;
    }
    if (q != NULL){
        cTail->next = q;
    }
}



// void merge(Node *A,Node *B,Node *&C){   //书上示例代码
//     Node *p = A->next;
//     Node *q = B->next;
//     Node *r;
//     C = A;
//     C->next = NULL;
//     free(B);
//     r = C;
//     while (p != NULL && q != NULL){
//         if (p->data <= q->data){
//             r->next = p;
//             p = p->next;
//             r = r->next;
//         }else{
//             r->next = q;
//             q = q->next;
//             r = r->next; 
//         }    
//     }
//     r->next = NULL;
//     if (p != NULL) r->next = p;
//     if(q != NULL) r->next = q;
// }
int main(){
    Node *list1 = (Node *)malloc(sizeof(Node));
    Node *list2 = (Node *)malloc(sizeof(Node));
    Node *list3 = (Node *)malloc(sizeof(Node));
    init(list1);
    init(list2);
    init(list3);
    for(int i=5;i>=0;i--){
        listCreate(list1,i+1);   //生成的链表:123456
        listCreate(list2,2*i); //02468 10      //最后合并的链表:01223445668 10
    }//先生成两条链表,方便检验
 
    merge(list1,list2,list3);
    Traversal(list3);
    getchar();
    return 0;
}
//使用malloc需要使用库stdlib.h
// 定义节点结构体要用如下格式:
// typedef struct Node{
//  int data;
//  Node *next;
// }Node;
//链表创建一个节点的方法:
//Node *p = (Node*)malloc(sizeof(Node));
 
// 尾插法插入节点:
// 首先定义一个尾节点tail,并让tail指向链表list的尾部
// 每插入一个节点p时,使用tail->next = p将新节点接入链表的尾部,这时tail指向的就不是链表的最后一个节点了,需要让tail指向最后一个节点
// 再用tail = p使尾节点tail重新指向链表的尾部
//假如p是一个结构体变量(定义方法:NODE p),就用‘ . ’
//假如p是一个结构体指针(定义方法 NODE *p),就用' -> '
//函数传参问题:
//假如p是一个结构体变量(定义方法:NODE p),传参时参数为 NODE &p
//假如p是一个结构体指针(定义方法 NODE *p),传参时参数为 NODE *&p



//链表类型问题:
// 有头节点:链表开头节点的数据域不存数据,从开头节点的下一个节点开始存数据,开头节点的下一个节点是第一个节点
// 没有头节点:链表开头节点数据域存放数据,开头节点即是链表的第一个节点
原文地址:https://www.cnblogs.com/BreezeFeng/p/13946464.html