算法刷题-线性表1-链表的合并

作者:倾斜的正弦波
运行环境:windows10+vs2015
注:所有代码都是亲自运行成功的


/*******************************************************************
题目描述:
假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。
请编写算法将这两个单链表归并为一个按元素值递减次序555排列的单链表,
并要求利用原来两个单链表的结点存放归并后的单链表。
分析:
因为两链表已按元素值递增次序排列,将其合并时,均从第一个结点起进行比较,
将小的链入链表中,同时后移链表工作指针。该问题要求结果链表按元素值递减次序排列。
故在合并的同时,将链表结点逆置。(逆置链表可用头插法)
变题2: 合并后链表递增(可用尾插法)
********************************************************************/

// link_01.cpp : 定义控制台应用程序的入口点。
//

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

#define  SIZE_A 10
#define  SIZE_B 5
int data_A [SIZE_A] = { 1,3,5,7,8,9,111,222,333,5555 };
int data_B [SIZE_B] = {2,8,19,22,10000};

typedef  struct Link
{
    int data;
    struct Link *next;
}Link;

Link *listA;
Link *listB;

void InitList(Link *&head)//初始化单链表  生成头结点
{
    head = (Link*)malloc(sizeof(Link));
    head->next = NULL;
}

//尾插法,依次将元素放在前一个元素后方  
void CreateListA(Link *&head, int a[], int n)
{
    Link *r, *t;//建立两个指针  
    /*head=(LinkList*)malloc(sizeof(LinkList));//为头结点分配空间
    head->next=NULL;*/
    r = head;
    for (int i = 0; i<n; i++)
    {
        t= (Link*)malloc(sizeof(Link));  //生成节点
        t->data = a[i];  //赋值
        r->next = t;     //插入到链表后
        r = t;           //是r不断更新为所插入的下一个元素,再次进入循环  
    }//通过for循环实现尾插法  
    r->next = NULL;
}


void TraverseList(struct Link * pHead)
{
    struct Link * p = pHead->next;
    int i = 0;
    if (pHead->next == NULL)
    {
        printf("链表为空!");
    }
    else
    {
        while (p != NULL)
        {
            printf("data[%d]->%d\n",i, p->data);
            p = p->next;
            i++;
        }

    }
}


/*****************************************************************************  
题目描述:    
    假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。
    请编写算法将这两个单链表归并为一个按元素值递减次序555排列的单链表,
    并要求利用原来两个单链表的结点存放归并后的单链表。
分析:
因为两链表已按元素值递增次序排列,将其合并时,均从第一个结点起进行比较,
将小的链入链表中,同时后移链表工作指针。该问题要求结果链表按元素值递减次序排列。
故在合并的同时,将链表结点逆置。(逆置链表可用头插法)

变题2: 合并后链表递增(可用尾插法)

******************************************************************************/

void Link_union(Link *la,Link *lb)
{

    Link *pa, *pb, *r;
    pa = la->next;
    pb = lb->next;
    la->next = NULL;
    while (pa&&pb)
    {
        if (pa->data<=pb->data)
        {
            r = pa->next;
            pa->next = la->next;
            la->next = pa;
            pa = r;
        }
        else
        {
            r = pb->next;
            pb->next = la->next;
            la->next = pb;
            pb = r;
        }

    }
    while (pa)
    {
        r = pa->next;
        pa->next = la->next;
        la->next = pa;
        pa = r;
    }
    while (pb)
    {
        r = pb->next;
        pb->next = la->next;
        la->next = pb;
        pb = r;
    }

}


//变题2  合并后是递增   
void  Link_union2(Link *la, Link *lb)
{
    Link *pa, *pb, *r,*t;
    pa = la->next;
    pb = lb->next;

    la->next = NULL; //a默认为合并的头
    t = la; //标记尾部
    while (pa&&pb)
    {
        if (pa->data <= pb->data)
        {
            r = pa->next;//用于更新比较的指针
            pa->next = NULL;
            //插入到尾部
            t->next = pa;
            //更新尾部
            t = pa;
            //更新pa;
            pa = r;
        }
        else
        {
            r = pb->next;//用于更新比较的指针
            pb->next = NULL;
            //插入到尾部
            t->next = pb;
            //更新尾部
            t = pb;
            //更新pa;
            pb = r;
        }

    }
    if (pa)
    {
        t->next = pa;
    }
    if (pb)
    {
        t->next = pb;
    }


}

int main()
{

    //初始化头结点
    InitList(listA);
    InitList(listB);

    //生成链表AB

    CreateListA(listA,data_A, SIZE_A);
    CreateListA(listB, data_B, SIZE_B);


    //打印链表AB
    printf("---------------链表A-----------------:\n");
    TraverseList(listA);
    printf("---------------链表B-----------------:\n");
    TraverseList(listB);

    //合并链表
    Link_union(listA, listB);

    printf("-----------------------------------合并后的链表:----------------------------\n");
    TraverseList(listA);

    return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值