利用线性链表基本操作完成两个有序线性表的合并

La、Lb线性链表升序排列,将结果放在Lc链表里。之前有文章写过两个有序链表的合并

区别在于,前面的做法是保留La的头节点,free掉Lb的头节点,将余下节点串起来。这种方法是面向过程编程

而现在讨论的做法,是单独建立一个Lc链表,利用一些已经写好的基本操作函数来完成,这种模块化编程做法实际上还简单些。不光模块函数里写不了几行,在调用这些函数时减少了不必要的琐碎过程的思考时间。

该做法的核心思想:将每轮比较过后偏小的那个节点从相应链表中删除(这是头节点的指针不会指向该节点了,但该节点的空间依旧保留),append(附加)到Lc链表。pa、pb始终指向当前La、Lb链表的第一个节点(头节点后面那个),最后会free掉La、Lb的头节点

代码如下:

#define ERROR 0
#define OK 1
typedef int Status;
typedef struct LNode
{
    ElementType data;
    struct LNode *next;
} *PtrToNode;

typedef struct //查下struct的格式
{
    PtrToNode head,tail;
    int len;    
}LinkList;

Status initList(LinkList &L) {//申明结构体变量要不要malloc?
    L.len = 0;
    L.head = L.tail = (struct LinkList *)malloc(sizeof(struct LinkList));//shi bu shi struct LinkList    
    return OK;
}

int getCurElem(PtrToNode p) {
    return p->data;
}

PtrToNode getHead(LinkList &L) {
    return L.head;
}

PtrToNode NextPos(LinkList &L,PtrToNode node) {
    return node->next;
}

void delFirst(LinkList &L,PtrToNode q) {
    head = getHead(L);
    q = head->next;
    head->next = head->next->next;
}

void append(LinkList &L,PtrToNode q) {
    L.tail->next = q;
    L.tail = q;
}

void freeNode(PtrToNode node) {
    free(node);
}

Status MergeList(LinkList &La,LinkList &Lb,LinkList &Lc) {
    PtrToNode p;
    int a,b;
    if(!initList(Lc)) return ERROR;
    PtrToNode ha = getHead(La);
    PtrToNode hb = getHead(Lb);
    PtrToNode pa = NextPos(La,ha);
    PtrToNode pb = NextPos(Lb,hb);
    while(pa && pb) {
        a = getCurElem(pa);
        b = getCurElem(pb);
        if(a <= b) {
            delFirst(La,q);//将首节点删除,并将地址赋给q
            append(Lc,q);
            pa = NextPos(La,ha);
        } else {
            delFirst(Lb,q);
            append(Lc,q);
            pb = NextPos(Lb,hb);
        }
    }

    if(pa) {
        append(Lc,pa);
    } else {
        append(Lc,pb);
    }

    freeNode(ha); freeNode(hb);
    return OK;
}
View Code
原文地址:https://www.cnblogs.com/gabygoole/p/5554866.html