PAT 1025. 反转链表 (25)

代码戳:https://github.com/laixiaolian/object-oriented

1、题目大意:

给定一个常数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

2、代码:

#include<stdio.h>
typedef struct link
{
    int address;
    int data;
    int nextaddr;
    struct link *next;//指向下个节点的指针
} Link;
int i=1;
int data[100004];
int next[100004];
int temp;
int num=0;
Link a[100004];

//创建链表
void create(Link *head)
{
    i = 1;
    while (1)
    {
    	    if (a[i-1].nextaddr == -1)
	    {
		    a[i-1].next = NULL;
		    num = i-1;
		    break;
	    }

	    a[i].address = a[i-1].nextaddr;
	    a[i].data = data[a[i].address];
	    a[i].nextaddr = next[a[i].address];
	    a[i-1].next = a+i;
	    i++;
    }
}

//链表反转
Link *listReverse(Link *head, int k)
{
    int count=1;
    Link *s=head->next;
    Link *old=s->next;
    Link *temp=NULL;

    while(count<k)
    {
	    temp=old->next;
	    old->next=s;
	    old->nextaddr=s->address;
	    s=old;  //s向后走一个节点
	    old=temp;  //temp向后走一个节点
	    count++;
    }

    //使反转后的最后一个节点指向下一段子链表的第一个节点
    head->next->next=old;

    if(old!=NULL)
    {
	    head->next->nextaddr=old->address;	//修改next值,使它指向下一个节点的位置
    }
    else
    {
	    //如果old为NULL,即没有下一个子链表,那么反转后的最后一个节点即是真个链表的最后一个节点
	    head->next->nextaddr=-1;
    }
    return s;
}
int main()
{
    int firstaddr;
    int n=0,k=0;
    Link *head;
    scanf("%d%d%d",&firstaddr,&n,&k);
    a[0].nextaddr=firstaddr;
    for(; i<n+1; i++)
    {
	    scanf("%d",&temp);
	    scanf("%d %d",&data[temp],&next[temp]);
    }
    create(head);

    Link *p=a; //p指向头结点
    Link *q=NULL;//反转链表函数的返回值
    if(k<=num)
    {
	    for(i=0; i<(num/k); i++)
	    {
		    q=listReverse(p,k);
		    p->next=q; // 第一次执行,a[0]->next 指向第一段子链表反转的第一个节点
		    p->nextaddr=q->address;  // 更改Next值,指向逆转后它的下一个节点的位置

		    //使p指向下一段需要反转的子链表的头结点
		    int j=0;
		    while(j<k)
		    {
			    p=p->next;
			    j++;
		    }
	    }
    }
    p=a;
    while(p->next!=NULL)
    {
	    p=p->next;
	    if(p->nextaddr!=-1)
	    {
		    printf("%05d %d %05d\n",p->address,p->data,p->nextaddr);
	    }
	    else
	    {
		    printf("%05d %d -1\n",p->address,p->data);
	    }
    }
    return 0;
}

3、问题:

在输入temp、data[temp]和next[temp]时我开始的时候是一起输入的,即scanf("%d%d%d",&temp,&data[temp],&next[temp]),但是结果输出的时候只能输出一行数字,我也不知道为什么会这样!!!

posted @ 2016-05-20 22:26  laixl  阅读(237)  评论(0编辑  收藏  举报