1025. 反转链表 (25)

1025. 反转链表 (25)

题目
给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转。例如:给定L为1→2→3→4→5→6,K为3,则输出应该为3→2→1→6→5→4;如果K为4,则输出应该为4→3→2→1→5→6,即最后不到K个元素不反转。

输入格式:

每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址、结点总个数正整数N(<= 105)、以及正整数K(<=N),即要求反转的子链结点的个数。结点的地址是5位非负整数,NULL地址用-1表示。

接下来有N行,每行格式为:

Address Data Next

其中Address是结点地址,Data是该结点保存的整数数据,Next是下一结点的地址。

输出格式:

对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。

输入样例:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
输出样例:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1

思路
模拟真实链表在内存中的储存情况。。。写的吐血,刚开始连接链表的时候就超时了,最后排序再查找才解决超时的问题。
反转,看了姥姥教的方法,用链表的真实反转方式,害怕。。。一个新手,能理解也是不容易。。。
代码

#include <stdio.h>
#include <stdlib.h>
typedef struct node *L;
typedef struct polynode *LL;
struct node {
    int address;//当前节点模拟地址,头结点存储的是反转个数
    int data;//存储数据,头结点存储的是节点总个数
    int addressLink;//存储下一个结点的模拟地址,头结点存储的是第一个结点的模拟地址
    L link;//真实的下一个结点的地址
};
struct polynode {
    int address;
    int data;
    int addressLink;
};
L inputFunc();
LL find(int addressLink,struct polynode Node[],int N);
int cmp(const void *a,const void *b);
L reverseList(L listP);
L Reverse(L head,int K);
void print(L listP);
void Attach (int a,int b,int c,L *Rearp );

int main(void)
{
    L listP;
    listP = inputFunc();
    print(reverseList(listP));
    return 0;
}
L reverseList(L listP)
{
    int K=listP->address;
    int N=listP->data;
    int i;
    //第一个反转;
    if(K==1)return listP;
    L head=listP;
    int cnt=1;
    L newp,oldp,temp;
    newp=head->link;
    oldp=newp->link;
    while(cnt<K)
    {
        int flag=1;
        if(oldp->addressLink==-1)flag=0;
        temp=oldp->link;
        oldp->addressLink=newp->address;
        oldp->link=newp;
        newp=oldp;
        if(flag)oldp=temp;
        cnt++;
    }
    head->link->addressLink=oldp->address;
    head->link->link=oldp;
    head=head->link;
    listP->addressLink=newp->address;
    listP->link=newp;
    for(i=1;i<N/K;i++)
        head=Reverse(head,K);
    if(N%K==0||N==K)
    {
        head->link=NULL;
        head->addressLink=-1;
    }
    return listP;
}
L Reverse(L head,int K)
{
    L listP=head->link;
    int cnt=1;
    L newp,oldp,temp;
    newp=head->link;
    oldp=newp->link;
    while(cnt<K)
    {
        int flag=1;
        if(oldp->addressLink==-1)flag=0;
        temp=oldp->link;
        oldp->addressLink=newp->address;
        oldp->link=newp;
        newp=oldp;
        if(flag)oldp=temp;
        cnt++;
    }
    listP->addressLink=oldp->address;
    listP->link=oldp;

    head->addressLink=newp->address;
    head->link=newp;
    return listP;
}
L inputFunc()
{
    int firstAddress;
    int N,i,reverseNums,count = 0;
    L listP,Rear;
    listP = (L)malloc(sizeof(struct node));
    listP->link=NULL;
    Rear=listP;
    scanf("%d %d %d",&firstAddress,&N,&reverseNums);
    listP->address=reverseNums;
    listP->addressLink=firstAddress;
    struct polynode Node[N];
    for(i=0;i<N;i++)
        scanf("%d %d %d",&Node[i].address,&Node[i].data,&Node[i].addressLink);
    qsort(Node,N,sizeof(Node[0]),cmp);
    while(Rear->addressLink!=-1)
    {
        LL Nnode=find(Rear->addressLink,Node,N);
        count ++;
        Attach(Nnode->address,Nnode->data,Nnode->addressLink,&Rear);
    }
    listP->data = count;
    return listP;
}
LL find(int addressLink,struct polynode Node[],int N)
{
    int L=0;
    int R=N-1;
    while(L<=R)
    {
        int mid=L+(R-L)/2;
        if(addressLink==Node[mid].address)
            return Node+mid;
        else if(addressLink>Node[mid].address)
            L=mid+1;
        else
            R=mid-1;
    }
    return NULL;
}
int cmp(const void *a,const void *b)
{
    return (*(struct polynode *)a).address>(*(struct polynode *)b).address?1:-1;
}
void Attach (int a,int b,int c,L *Rearp )//将找到的结点添加到列表中
{
    L P;
    P=(L)malloc(sizeof(struct node));
    P->address=a;
    P->data=b;
    P->addressLink=c;
    (*Rearp)->link=P;
    *Rearp=P;
}
void print(L listP)
{
    L P = listP->link;
    while(P)
    {
        printf("%05d %d ",P->address,P->data);
        if((P->addressLink)==-1)
            printf("%d",P->addressLink);
        else
            printf("%05d",P->addressLink);
        printf("\n");
        P=P->link;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值