Reversing Linked List

给出 1 2 3 4 5 6
k = 3 得到 3 2 1 6 5 4
k = 4 得到 4 3 2 1 5 6
输入:
第一行给出
起始地址 总共要给出的结点个数 K的值
下面每一行
地址 数据 下一个的地址
Address Data Next
输出
按输入的形式输出,不过null用-1表示而已

#include <stdio.h>
//读取数据应采取数组的形式 防止无用结点
/*00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218*/
typedef int POS;
typedef struct addre{
    int data;
    POS next;
}node;
node address[100001];//模拟地址数组
//这一个函数来自于第5周的周练习
void K_Reverse( POS L, int K ){
    int length = 0;//记录链表长度
     POS head = address[L].next;//保存头结点的信息
    while(head != -1){
        ++length;
        head = address[head].next;
    }
    int n = length / K;//需要逆转几次
    //p指针用于遍历给定的链表 temp指针用于尾插法的实现 H 指针用于实现多次插入
   // rear指针用于保存每段链表最后的那个结点的数据 方便作为下一次遍历的头结点
    POS p = address[L].next,temp = -1,H = L,rear = -1;
    address[H].next= -1;
    //第一个循环控制需要做的次数
    while(n--){
        //这个循环主要为了每次需要的逆转的个数
        for(int c = 0; c < K;++c){
            if(c == 0)//由于采取的是尾插法 所以rear需要保存的是第一个结点的数据
                rear = p;
            //正常尾插操作
            temp = p;
            p =address[p].next;
            address[temp].next = address[H].next;
            address[H].next = temp;
        }
        //为下一次遍历准备头结点
        H = rear;
        address[H].next = -1;
    }
    address[H].next = p;//将不需要链接的结点放在后面 如果正好连接完毕 则p为空 操作统一
}
int main (){
    int firstaddress,N,K,add,data,next;
    scanf("%d %d %d",&firstaddress,&N,&K);
    //读取数据
    for(int i = 0; i < N;++i){
        scanf("%d %d %d",&add,&data,&next);
        address[add].data = data;
        address[add].next = next;
    }
    address[100000].next = firstaddress;
    K_Reverse(100000,K);
    //打印数据
    POS h = address[100000].next;
    for(int i = 0; i < N && h != -1;++i){
        if(address[h].next == -1)
            printf("%05d %d %d\n",h,address[h].data,address[h].next);
        else
        printf("%05d %d %05d\n",h,address[h].data,address[h].next);
        h = address[h].next;
    }
    return 0;
}

选取数据结构

由于此前我写过这题的两个简单变种,写这题借鉴之前的两个题目的思想与函数,写得没有感觉特别困难。
首先还是选取数据结构的问题,很明显,这是要你用数组去模拟实际的内存。采取静态链表的方式去存放数据。
(我之前写这个题目的变种的时候,没有采取静态链表,结果被多余的结点坑了,然后想了一上午,终于顿悟,有多余的结点,当时还是我完全没学数据结构的情况,现在想起来真辛酸。)

逆转K链表

这个问题解决了,其实事情就很简单了。现在还剩下的任务就是怎么去做到K逆转链表。
对于这个问题,用正常思路解决就好。
整体思路:

首先计算这个链表的长度,然后算下要逆转几次。
	每次逆转,记录下一次逆转需要的头结点。
	逆转完成后,把头节点更新尾记录的头节点,进行下一次逆转。
将剩下的链表连接到已逆转完的链表上
返回新逆转链表的头节点

链表的逆转其实就是借助于头插法实现的,当然你用栈也是可以达到效果的。K段逆转也是一样的,不过是分段头插而已。

这次就不给出我的测试数据了,下面是实验的测试数据
Reversing Linked List

上一篇:2016最新广告法禁用词汇大全


下一篇:c++友元函数和友元类详解