PAT : 数据结构与算法题目集(中文)7-51 两个有序链表序列的合并

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/belous_zxy/article/details/87025727

目录

1.结构体指针构建(C++11)

2.结构体数组构建(C)


1.结构体指针构建(C++11)

#include <iostream>
#include <string>
#include <vector>
using namespace std;
using Link = struct LinkNode *;
struct LinkNode
{
    int Value;
    Link Next;
};
int getdigit(void)
{
    int digit{0}, symbol{1};
    bool isp{true};
    while (1)
    {
        char ch = getchar();
        if (ch == ' ' || ch == '\n' || ch == EOF || ch == '\t')
        {
            if (isp)
                continue;
            return digit * symbol;
        }
        isp = false;
        if (ch == '-')
            symbol = -1;
        else
            digit = digit * 10 + ch - '0';
    }
}
void putdigit(int digit)
{
    if (digit < 0)
    {
        putchar('-');
        putdigit(-digit);
    }
    if (digit >= 10)
        putdigit(digit / 10);
    putchar(digit % 10 + '0');
}
Link CreatLink(void)
{
    int temp = getdigit();
    if (temp == -1)
        return nullptr;
    Link L = static_cast<Link>(malloc(sizeof(LinkNode)));
    Link T = L;
    T->Value = temp;
    temp = getdigit();
    while (temp != -1)
    {
        T->Next = static_cast<Link>(malloc(sizeof(LinkNode)));
        T = T->Next;
        T->Value = temp;
        temp = getdigit();
    }
    T->Next = nullptr;
    return L;
}
Link NewLinkNode(int value)
{
    Link L = static_cast<Link>(malloc(sizeof(LinkNode)));
    L->Value = value;
    L->Next = nullptr;
    return L;
}
Link AssumeLink(Link a, Link b)
{
    if (a == nullptr)
        return b;
    if (b == nullptr)
        return a;
    Link Tempa{a}, Tempb{b}, T{NewLinkNode(0)};
    Link Tmp = T;
    while (Tempa != nullptr && Tempb != nullptr)
    {
        if (Tempa->Value < Tempb->Value)
        {
            Tmp->Next = NewLinkNode(Tempa->Value);
            Tempa = Tempa->Next;
        }
        else
        {
            Tmp->Next = NewLinkNode(Tempb->Value);
            Tempb = Tempb->Next;
        }
        Tmp = Tmp->Next;
    }
    while (Tempa != nullptr)
    {
        Tmp->Next = NewLinkNode(Tempa->Value);
        Tempa = Tempa->Next;
        Tmp = Tmp->Next;
    }
    while (Tempb != nullptr)
    {
        Tmp->Next = NewLinkNode(Tempb->Value);
        Tempb = Tempb->Next;
        Tmp = Tmp->Next;
    }
    Tmp->Next = nullptr;
    Tmp = T;
    T = T->Next;
    free(Tmp);
    return T;
}
void PrintLink(Link L)
{
    if (L == nullptr)
        puts("NULL");
    else
    {
        putdigit(L->Value);
        L = L->Next;
        while (L != nullptr)
        {
            putchar(' ');
            putdigit(L->Value);
            L = L->Next;
        }
        putchar('\n');
    }
}
void FreeLink(Link &L)
{
    while (L != nullptr)
    {
        Link Del = L;
        L = L->Next;
        free(Del);
    }
    L = nullptr;
}
int main(int argc, char *argv[])
{
    Link Add1{CreatLink()}, Add2{CreatLink()};
    Link Ass = AssumeLink(Add1, Add2);
    PrintLink(Ass);
    // FreeLink(Ass);
    // FreeLink(Add1);
    // FreeLink(Add2);
    return EXIT_SUCCESS;
}

链表销毁也会占不少时间,可以略去。。。2333

 2.结构体数组构建(C)

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#define CursorMax 2100000

typedef struct node
{
    int Element;
    int Next;
} Node;
Node CursorSpace[CursorMax];

int getdigit(void);
void putdigit(int temp);

static int CursorAlloc(void)
{
    int P;
    P = CursorSpace[0].Next;
    if (!P)
        return -1;
    CursorSpace[0].Next = CursorSpace[P].Next;
    return P;
}
static void CursorFree(int P)
{
    if (!P)
        return;
    CursorSpace[P].Next = CursorSpace[0].Next;
    CursorSpace[0].Next = P;
    return;
}
int LinkGet(void)
{
    int re = 0, temp = 0, sp = 0, in;
    while ((in = getdigit()) != -1)
    {
        temp = CursorAlloc();
        CursorSpace[temp].Element = in;
        CursorSpace[temp].Next = 0;
        if (!re)
            sp = re = temp;
        else
        {
            CursorSpace[sp].Next = temp;
            sp = temp;
        }
    }
    return re;
}
void LinkPrint(int P)
{
    if (!P)
    {
        putchar('N');
        putchar('U');
        putchar('L');
        putchar('L');
        putchar('\n');
        return;
    }
    putdigit(CursorSpace[P].Element);
    P = CursorSpace[P].Next;
    while (P)
    {
        putchar(' ');
        putdigit(CursorSpace[P].Element);
        P = CursorSpace[P].Next;
    }
    putchar('\n');
    return;
}
static void CursorInit(void)
{
    CursorSpace[CursorMax - 1].Next = 0;
    for (int i = 0; i < CursorMax - 1; i++)
        CursorSpace[i].Next = i + 1;
    return;
}
int LinkAssum(int a, int b)
{
    if (!a)
        return b;
    if (!b)
        return a;
    int sp, re = 0, temp;
    while (a && b)
    {
        sp = CursorAlloc();
        if (CursorSpace[a].Element <= CursorSpace[b].Element)
        {
            CursorSpace[sp].Element = CursorSpace[a].Element;
            a = CursorSpace[a].Next;
        }
        else
        {
            CursorSpace[sp].Element = CursorSpace[b].Element;
            b = CursorSpace[b].Next;
        }
        if (!re)
            re = temp = sp;
        else
        {
            CursorSpace[temp].Next = sp;
            temp = sp;
        }
    }
    while (a)
    {
        sp = CursorAlloc();
        CursorSpace[sp].Element = CursorSpace[a].Element;
        a = CursorSpace[a].Next;
        if (!re)
            re = temp = sp;
        else
        {
            CursorSpace[temp].Next = sp;
            temp = sp;
        }
    }
    while (b)
    {
        sp = CursorAlloc();
        CursorSpace[sp].Element = CursorSpace[b].Element;
        b = CursorSpace[b].Next;
        if (!re)
            re = temp = sp;
        else
        {
            CursorSpace[temp].Next = sp;
            temp = sp;
        }
    }
    CursorSpace[temp].Next = 0;
    return re;
}
void LinkDel(int P)
{
    if (!P)
        return;
    while (P)
    {
        int temp = P;
        P = CursorSpace[P].Next;
        CursorFree(temp);
    }
    return;
}
int main(int argc, char **argv)
{
    CursorInit();
    int link1 = LinkGet();
    int link2 = LinkGet();
    link1 = LinkAssum(link1, link2);
    LinkPrint(link1);
    //LinkDel(link1);
    //LinkDel(link2);
    return EXIT_SUCCESS;
}

int getdigit(void)
{
    int temp = 0;
    int symbol = 1;
    char ch;
    bool isfis = true;
    while (1)
    {
        ch = getchar();
        if (ch == ' ' || ch == '\n' || ch == EOF)
        {
            if (isfis)
                continue;
            return temp * symbol;
        }
        if (ch == '-')
            symbol = -1;
        else
            temp = temp * 10 + ch - '0';
        isfis = false;
    }
}
void putdigit(int temp)
{
    if (temp < 0)
    {
        putchar('-');
        temp = -temp;
    }
    if (temp >= 10)
        putdigit(temp / 10);
    putchar(temp % 10 + '0');
}

结构体数组模拟实现链表,数组下标代表地址;预先初始化所有地址都连在下标 [0] 处,构成一个堆栈,申请和释放空间就是从下标 [0] 处出栈、入栈。

堆栈初始化需要一定的时间,但大规模输入下相比于指针实现的链表速度略快一点;大规模输入时链表申请的空间大小也远远大于了结构体数组的大小。

但是需要预先确定最大数组,本题至少 2100000 左右,,一次次提交试出来的。。。

总之,指针实现方法思路简单且稳定;结构体数组下标法在大规模输入时,内存损耗上更占优势~~~

END

猜你喜欢

转载自blog.csdn.net/belous_zxy/article/details/87025727