本文提供pta重排链表的两种方法,两种都是使用数组模拟链表的操作,区别在与所使用空间的大小不同,从而导致时间复杂度也不同。
重排链表的第一种方法:
这种方法节省了很多空间,但在N非常大时会超时。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct Node* List;
struct Node {
int Data;
int Adr;
int Next;
};
int main() {
int FAdr, n, i, j;
scanf("%d %d", &FAdr, &n);
List L1;
L1 = (List)malloc(n * sizeof(struct Node));
int* a;
a = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; i++) {
scanf("%d %d %d", &L1[i].Adr, &L1[i].Data, &L1[i].Next);
if (L1[i].Adr == FAdr) {
a[0] = i;
}
}
for (i = 1; i < n && L1[a[i - 1]].Next != -1; i++) {
for (j = 0; j < n; j++) {
if (L1[a[i - 1]].Next == L1[j].Adr) {
a[i] = j;
break;
}
}
}
if (i < n) n = i;
for (i = 0; i < n / 2; i++) {
printf("%05d %d %05d\n", L1[a[n - 1 - i]].Adr, L1[a[n - 1 - i]].Data, L1[a[i]].Adr);
if (i == n / 2 - 1 && n % 2 == 0)
printf("%05d %d %d\n", L1[a[i]].Adr, L1[a[i]].Data, -1);
else
printf("%05d %d %05d\n", L1[a[i]].Adr, L1[a[i]].Data, L1[a[n - 2 - i]].Adr);
}
if (n % 2 == 1) printf("%05d %d %d\n", L1[a[n / 2]].Adr, L1[a[n / 2]].Data, -1);
return 0;
}
第二种方法:使用数组模拟链表操作,占用较大空间但时间复杂度小。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct Node {
int Data;
int Adr;
int Next;
}List;
List L[100000];
List Res[100000];
int main() {
int FAdr, n, i, rnum;
scanf("%d %d", &FAdr, &n);
int Adr, Data, Next;
for (i = 0; i < n; i++) {
scanf("%d %d %d", &Adr, &Data, &Next);
L[Adr].Adr = Adr;
L[Adr].Data = Data;
L[Adr].Next = Next;
}
Adr = FAdr;
rnum = 0;
while (Adr != -1) {
Res[rnum].Adr = L[Adr].Adr;
Res[rnum].Data = L[Adr].Data;
Adr = L[Adr].Next;
rnum++;
}
for (i = 0; i < rnum / 2; i++) {
printf("%05d %d %05d\n", Res[rnum - 1 - i].Adr, Res[rnum - 1 - i].Data, Res[i].Adr);
if (i == n / 2 - 1 && n % 2 == 0)
printf("%05d %d %d\n", Res[i].Adr, Res[i].Data, -1);
else
printf("%05d %d %05d\n", Res[i].Adr, Res[i].Data, Res[rnum - 2 - i].Adr);
}
if (n % 2 == 1) printf("%05d %d %d\n", Res[rnum / 2].Adr, Res[rnum / 2].Data, -1);
return 0;
}