02-线性结构3 Reversing Linked List   (25分)

来源:互联网 发布:来自星星的你知我是 编辑:程序博客网 时间:2024/06/07 00:36

Given a constant KK and a singly linked list LL, you are supposed to reverse the links of everyKK elements on LL. For example, given LL being 1→2→3→4→5→6, if K=3K = 3, then you must output 3→2→1→6→5→4; ifK=4K = 4, you must output 4→3→2→1→5→6.

Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, a positiveNN (≤10510^5) which is the total number of nodes, and a positive KK (N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.

Then NN lines follow, each describes a node in the format:

Address Data Next

where Address is the position of the node,Data is an integer, and Next is the position of the next node.

Output Specification:

For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:

00100 6 400000 4 9999900100 1 1230968237 6 -133218 3 0000099999 5 6823712309 2 33218

Sample Output:

00000 4 3321833218 3 1230912309 2 0010000100 1 9999999999 5 6823768237 6 -1

思路:

1、用结构数组模拟链表

2、题意是满足K个结点的一段链表就要逆转,而不满K个结点的不需要逆转(比如有10个结点的链表,K为4,那么分为两部分:0123,4567需要逆转,89只有2个不逆转)

3、用三个指针New,Old,Tmp来完成一段(K个结点)的链表的逆转(具体看mooc上的思路);对应Reverse函数

4、mooc上只给了一段链表的逆转,而没有给整个的,所以需要自己写整个链表的逆转;对应ReversingLinkedList函数

#include <stdio.h>#include <stdlib.h>#define MaxSize 100000typedef int Ptr;//结构数组模拟链表struct node{int key;Ptr next;}list[MaxSize];//逆转某一段含K个结点的链表Ptr Reverse ( Ptr head, int K ) {Ptr New, Old, Tmp; //New指向逆转链表表头,Old指向未逆转表头,Tmp记录Old后一个结点int cnt = 1;New = head;Old = list[New].next;while ( cnt < K ) {Tmp = list[Old].next; //记录Old下一个结点,防止逆转指针后丢失list[Old].next = New; //逆转指针New = Old; Old = Tmp; //New,Old向后转移一个cnt++;}list[head].next = Old; //原来的第一个结点逆转后变为最后一个结点,并连接剩下未逆转的元素return New;}//判断是否需要逆转int NeedReverse ( Ptr head , int K) {int i;for( i = 1; list[head].next != -1; head = list[head].next ) {i++;if ( i == K ) return 1; //还有K个或以上结点,需要逆转}return 0; //不足K个结点,不需要逆转}//逆转整个链表Ptr ReversingLinkedList( Ptr head , int K ) {Ptr UnreversedHead = head;//未逆转的链表的第一个结点Ptr ListHead; //整个表的第一个结点Ptr TempTail; //临时表尾,用来连接下一段逆转的链表if ( NeedReverse( UnreversedHead, K ) ) { //第一次先判断是否需要逆转ListHead = Reverse( UnreversedHead, K ); //记住逆转后的整个链表的第一个结点TempTail = UnreversedHead; //记录此逆转链表的表尾UnreversedHead = list[TempTail].next; //记录未逆转链表的表头}else //链表结点个数小于K,无需逆转return head;while ( NeedReverse( UnreversedHead, K ) ) {list[TempTail].next = Reverse( UnreversedHead, K ); //上一个逆转链表的表尾与这个逆转链表的表头连接TempTail = UnreversedHead;UnreversedHead = list[TempTail].next;}return ListHead;}//输出链表void PrintLinkedList ( Ptr head ) {Ptr temp = head;for(; list[temp].next !=  -1;  temp = list[temp].next)printf("%05d %d %05d\n", temp, list[temp].key, list[temp].next);printf("%05d %d %d\n", temp, list[temp].key, list[temp].next);}int main(){Ptr ad, head;int N, K;scanf("%d %d %d", &head, &N, &K);for(int i = 0; i < N; i++){scanf("%d", &ad);scanf("%d %d", &list[ad].key, &list[ad].next);}PrintLinkedList( ReversingLinkedList( head, K ) );system("pause");return 0;}


原创粉丝点击