MOOC数据结构PTA-02-线性结构3 Reversing Linked List (25 分)
题目
Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=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 positive N (≤105) which is the total number of nodes, and a positive K (≤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 N 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 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
一、链表实现
题目要求对项目倒序,自然想到把每项定义成结构,顺序用静态链表的下表表示。
此方式逻辑功能虽然正确,但测试点5(最大N,最后剩K-1不反转)通不过:时间复杂度过高(O(N2)),导致超时。
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100000
typedef int ELEtype;
typedef struct {
ELEtype data;
int next;
}Node;
Node List[MAXSIZE];//Static linked list
void Print_list(Node* list , int First){
int index = First;
while(list[index].next != -1){
printf("%05d %d %05d\n",index,list[index].data,list[index].next);
index = list[index].next;
}
printf("%05d %d %d\n",index,list[index].data,-1);
return;
}
int find_pre(Node *list , int First ,int Cur){
int pre = First;
while(list[pre].next!=Cur){
pre = list[pre].next;
}
return pre;
}
int Reverse_Klist(Node *list , int *First , int K){
int index = *First;
for(int i = 1;i<K;i++){
index = list[index].next;
}
int new_first = index;//find the new_first
int next_one = list[new_first].next;//find the next_first
while(index!=*First){
int temp = find_pre(list,*First,index);
list[index].next = temp;
index = temp;
}
list[*First].next = next_one;
*First = next_one;
return new_first;
}
int Get_length(Node *list , int First){
int n = 0;
while(list[First].next!=-1){
n++;
First = list[First].next;
}
return n+1;
}
int Reverse_All(Node*list,int First,int K){
int N = Get_length(List,First);
int new_first = First;
if(K>1){
new_first = Reverse_Klist(list,&First,K);
while((N-K)/K>0){
int renew = find_pre(list,new_first,First);//find the last Ksequence's tail
list[renew].next = Reverse_Klist(list,&First,K);
N-=K;;
}
}
return new_first;
}
int main(){
int First,N,K;
scanf("%d%d%d",&First,&N,&K);
for (int i = 0;i<N;i++){
int address,data,next;
scanf("%d%d%d",&address,&data,&next);
List[address].data = data;
List[address].next = next;
}//creat the original linked list
int new_first = Reverse_All(List,First,K);
Print_list(List,new_first);
return 0;
}
二、数组实现(降低时间复杂度)
为了使时间复杂度降低,考虑将顺序单独写成数组,排序时只排序顺序这个数组,便可以不用像链表一样每次从头查找了。
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100000
typedef int ELEtype;
void print_list(ELEtype*list, int*order){
int i = 0;
while(order[i+1]!=-1){
printf("%05d %d %05d\n", order[i], list[order[i]], order[i+1]);
i++;
}
printf("%05d %d %d\n", order[i], list[order[i]], order[i+1]);
return;
}
int getlength(int*order){
int N = 0;
while(*(order++)!= -1)
N++;
return N;
}
void reverse_K(int*order, int K){
int temp[K];
for (int i = 0; i<K; i++)
temp[i] = *(order+i);
for(int i = 0; i < K; i++){
*(order+i) = temp[K-1-i];
}
return;
}
int reverse_all(int*order,int K){
int N = getlength(order);
int*ptr = order;
while(N/K>0){
reverse_K(ptr,K);
N-=K;
ptr+=K;
}
return;
}
int main(){
int first, N, K;
scanf("%d%d%d",&first, &N, &K);
//the list of data
ELEtype list[MAXSIZE];
int next_pos[MAXSIZE];
//the order list的顺序即为数组下标的顺序
int order[N+1];
for(int i = 0; i < N; i++){
int index, data, next;
scanf("%d%d%d",&index, &data, &next);
list[index] = data;
next_pos[index] = next;
}
//sort the list of order
for(int i = first,j = 0; i != -1; i = next_pos[i]){
order[j] = i;
j++;
order[j] = -1;
}
reverse_all(order,K);
print_list(list, order);
return 0;
}

浙公网安备 33010602011771号