我喜欢事实。
做为一个菜鸟,我用两个数组实现,第一个数组的下标就是该结点的地址,里面再存数据和下一结点的地址。用另外一个数组反向存储,即数组下标存储地址,里面存储的信息是它上一个结点的地址。剩下的就是慢慢找够K个反向输出,找输出。
下面是粗糙的代码。
#include <stdio.h>
#define MAX_N 100001
typedef struct node{
int address;
int data;
int next;
}node;
typedef struct F_node{
int data;
int next;
}F_node;
struct F_node F_N[MAX_N]; /* 数组下标为address 它的下一个结点为next */
int R_N[MAX_N]; /* 数组下标为next,它存储的值为address, 即下标的上一个结点 */
int first_a; /* 首地址 */
int K; /* 每K个节点翻转 */
int read_N();
int print_N();
int print_K_node(int i);
int print_remain_node(int i, int j);
int print_num(int x);
/********************************** 读取输入的数据 *********************************/
int read_N(){
int i, N;
struct node p;
scanf("%d %d %d", &first_a, &N, &K);
for(i = 0; i < N; ++i){
scanf("%d %d %d", &p.address, &p.data, &p.next);
F_N[p.address].data = p.data;
F_N[p.address].next = p.next;
R_N[p.next] = p.address;
}
}
/********************************* 输出数据 ****************************************/
int print_N(){
int i, j;
i = first_a; /* 从第一个地址开始 */
while(1){
for(j = 1; j < K; ++j){ /* 找够K个结点 */
if(F_N[i].next != -1)
i = F_N[i].next;
else
break;
}
if(j == K){ /* 如果找到了一组 */
print_K_node(i); /* 输出一组结点 */
if(F_N[i].next == -1) /* 后面再没有结点了 */
break; /* 结束 */
}
else{ /* 如果没有找够一组,i是最后一个结点的地址, 总共还有j个没输出 */
print_remain_node(i, j);/* 按原来的顺序输出最后j个结点 */
break; /* 结束 */
}
i = F_N[i].next; /* */
}
}
/*********************** 反向输出第一个结点地址为i的K个结点 *************************/
int print_K_node(int i){
int pos, j, n;
for(pos = i, j = 0; j < K; ++j ){
if(j < K-1){ /* 先输出本组K-1个结点 */
print_num(pos); /* 先把自己的地址输出去 */
printf(" %d ", F_N[pos].data); /* 输出数据 */
print_num(R_N[pos]); /* 输出pos的前一个结点地址 */
pos = R_N[pos]; /* pos定位到前一个结点,准备下一次的输出 */
}else{ /* 这是输出本组最后一个结点的时候 */
print_num(pos);
printf(" %d ", F_N[pos].data);
if(F_N[i].next != -1){ /* 如果本组第一个输出的结点后面还有结点 */
pos = F_N[i].next; /* 寻找下一K组结点的第一个地址 */
for(n = 1; n < K; ++n){
if(F_N[pos].next != -1)
pos = F_N[pos].next;
else
break;
}
if(n == K) /* 找到了 */
print_num(pos);
else /* 没有找到 */
print_num(F_N[i].next);
}else /* 若本组结点后面再无结点 */
printf("-1");
}
printf("\n");
}
return 0;
}
/**************** 按原来的输出输出剩余的j个结点,最后一个结点地址为i ****************/
int print_remain_node(int i, int j){
for(; j > 1; --j) /* 先退回到剩余结点的第一个结点地址 */
i = R_N[i];
while(i != -1){
print_num(i); /* 输出地址 */
printf(" %d ", F_N[i].data); /* 输出数据 */
if(F_N[i].next != -1) /* 若它的下一个结点不为-1 */
print_num(F_N[i].next); /* 输出下一个结点的笛子 */
else /* 若为最后一个结点的地址 */
printf("-1"); /* 结束 */
i = F_N[i].next;
printf("\n");
}
return 0;
}
/************************************* 输出x *****************************************/
int print_num(int x){
int i, j;
if(x < 10000){
for(i = 0, j = 10000; i < 5; ++i, j /= 10){
printf("%d", x / j);
x = x % j;
}
}else
printf("%d", x);
return 0;
}
int main(){
read_N();
print_N();
return 0;
}
/******************* 日记 ***************************/