用鏈表和大小可變的指針數組實現多個棧的建立與操作

朋友在刷PTA遇到了這樣一道有意思的題:
在這裏插入圖片描述
實現起來不難,但是總是提示時間超限或內存超限。
這裏給出輸出入和輸出示例:
輸入

2
2 15
1 1 10
1 1 11
1 2 12
1 2 13
3 1 2
1 2 14
2 1
2 1
2 1
2 1
2 1
3 2 1
2 2
2 2
2 2
3 7
3 1 2
3 1 3
3 2 1
2 1
2 2
2 3
2 3

輸出:

13
12
11
10
EMPTY
14
EMPTY
EMPTY
EMPTY
EMPTY
EMPTY
EMPTY

簡單的用二維數組開闢好空間顯然是行不通的,因而選擇使用鏈表:

typedef struct stack
{
    int n;
    struct stack* next;
}*sta,stack;

首先我們實現第一個操作將數據存入鏈表:

void opera1(sta head,int n)
{
    sta p=(sta)malloc(sizeof(stack));
    p->next=head->next;
    head->next=p;
    p->n=n;
    //printf("%d",p->n);
}

這裏直接採用了頭插法。這樣我們可以方便對棧頂進行操作。我們在實現第二種操作時就是利用這種特性:

void opera2(sta head)
{
    sta p;
    if(head->next==NULL)
        printf("EMPTY\n");
    else
    {
        p=head->next;
        printf("%d\n",p->n);
        head->next=p->next;
        free(p);
    }
}

接下來是方法3也是簡單的拼接操作,可以直接把鏈表拼接到頭部降低時間複雜度:

void opera3(sta head1,sta head2)
{
    sta p=head1;
    int i=0;
    while(p->next!=NULL)
    {
        p=p->next;
        i++;
    }
    if(i!=0)
    {
        p->next=head2->next;
        head2->next=head1->next;
        head1->next=NULL;
    }
}

爲了降低其對空間的佔用且符合規範,由於存在多組輸入我們要及時釋放內存:

void destroy(sta head)
{
    sta p=head;
    sta q;
    while(p!=NULL)
    {
        q=p->next;
        free(p);
        p=q;
    }
}

爲了進一步節約空間我們需要將指針數組的大小也可變,也就是創建一個指針的指針來作爲數組的首地址:

sta* head=NULL;

接下來只要根據需要分配空間就可以了:

head=(sta*)malloc(sizeof(sta)*n);

n爲我們需要的頭結點數量。
main函數裏通過switch語言調用各個方法,同時爲了避免空間浪費我們只在對應標號的棧被用到時創建頭結點。
接下來我們直接給出整個main函數的代碼:

int main()
{
    int t,i;
    scanf("%d",&t);
    for(i=0;i<t;i++)
    {
        int n,q,s,v,h1,h2;
        int j,k;
        int op;
        sta* head=NULL;
        scanf("%d %d",&n,&q);
        head=(sta*)malloc(sizeof(sta)*n);
        for(j=0;j<n;j++)
            head[j]=NULL;
        for(k=0;k<q;k++)
        {
            scanf("%d",&op);
            switch(op)
            {
            case 1:
                scanf("%d %d",&s,&v);
                s--;
                if(head[s]==NULL)
                {
                    head[s]=(sta)malloc(sizeof(sta));
                    head[s]->next=NULL;
                }
                opera1(head[s],v);
                break;
            case 2:
                scanf("%d",&s);
                s--;
                if(head[s]==NULL)
                {
                    head[s]=(sta)malloc(sizeof(sta));
                    head[s]->next=NULL;
                }
                //printf("%d",head[s]->next->n);
                opera2(head[s]);
                break;
            case 3:
                scanf("%d %d",&h1,&h2);
                h1--;
                h2--;
                if(head[h1]==NULL)
                {
                    head[h1]=(sta)malloc(sizeof(sta));
                    head[h1]->next=NULL;
                }
                if(head[h2]==NULL)
                {
                    head[h2]=(sta)malloc(sizeof(sta));
                    head[h2]->next=NULL;
                }

                opera3(head[h2],head[h1]);
            }
        }
        for(k=0;k<n;k++)
        {
            if(head[k]!=NULL)
                destroy(head[k]);
        }
    }
    return 0;
}

接下來我們給出整體代碼:

#include<stdio.h>
#include<stdlib.h>
typedef struct stack
{
    int n;
    struct stack* next;
}*sta,stack;

void opera1(sta head,int n)
{
    sta p=(sta)malloc(sizeof(stack));
    p->next=head->next;
    head->next=p;
    p->n=n;
    //printf("%d",p->n);
}

void opera2(sta head)
{
    sta p;
    if(head->next==NULL)
        printf("EMPTY\n");
    else
    {
        p=head->next;
        printf("%d\n",p->n);
        head->next=p->next;
        free(p);
    }
}

void opera3(sta head1,sta head2)
{
    sta p=head1;
    int i=0;
    while(p->next!=NULL)
    {
        p=p->next;
        i++;
    }
    if(i!=0)
    {
        p->next=head2->next;
        head2->next=head1->next;
        head1->next=NULL;
    }
}
void destroy(sta head)
{
    sta p=head;
    sta q;
    while(p!=NULL)
    {
        q=p->next;
        free(p);
        p=q;
    }
}
int main()
{
    int t,i;
    scanf("%d",&t);
    for(i=0;i<t;i++)
    {
        int n,q,s,v,h1,h2;
        int j,k;
        int op;
        sta* head=NULL;
        scanf("%d %d",&n,&q);
        head=(sta*)malloc(sizeof(sta)*n);
        for(j=0;j<n;j++)
            head[j]=NULL;
        for(k=0;k<q;k++)
        {
            scanf("%d",&op);
            switch(op)
            {
            case 1:
                scanf("%d %d",&s,&v);
                s--;
                if(head[s]==NULL)
                {
                    head[s]=(sta)malloc(sizeof(sta));
                    head[s]->next=NULL;
                }
                opera1(head[s],v);
                break;
            case 2:
                scanf("%d",&s);
                s--;
                if(head[s]==NULL)
                {
                    head[s]=(sta)malloc(sizeof(sta));
                    head[s]->next=NULL;
                }
                //printf("%d",head[s]->next->n);
                opera2(head[s]);
                break;
            case 3:
                scanf("%d %d",&h1,&h2);
                h1--;
                h2--;
                if(head[h1]==NULL)
                {
                    head[h1]=(sta)malloc(sizeof(sta));
                    head[h1]->next=NULL;
                }
                if(head[h2]==NULL)
                {
                    head[h2]=(sta)malloc(sizeof(sta));
                    head[h2]->next=NULL;
                }

                opera3(head[h2],head[h1]);
            }
        }
        for(k=0;k<n;k++)
        {
            if(head[k]!=NULL)
                destroy(head[k]);
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章