• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

Vigil

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

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 (≤10​5) 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;
}

image

posted on 2021-07-15 15:11  VigilYang  阅读(103)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3