B1025 反轉(zhuǎn)鏈表 (25分)

/*
題意:給一個(gè)鏈表,然后給出一個(gè)K,每K個(gè)節(jié)點(diǎn)反轉(zhuǎn)一次

解題:
1、定義及靜態(tài)鏈表,order表示在鏈表中的序號(hào),
2、初始化,令order的初值均為maxn,表示初始時(shí)所有節(jié)點(diǎn)為無(wú)效節(jié)點(diǎn)
3、由題目給出的鏈表首地址begi遍歷整條鏈表,并記錄每個(gè)有效節(jié)點(diǎn)在鏈表中的序號(hào),統(tǒng)計(jì)技術(shù)有效節(jié)點(diǎn)的個(gè)數(shù)count。
4、對(duì)節(jié)點(diǎn)進(jìn)行排序,按節(jié)點(diǎn)order從小到大排序
5、輸出鏈表,這個(gè)很煩
將n個(gè)節(jié)點(diǎn)分塊n/k塊,枚舉這些完整的塊,從后往前輸出節(jié)點(diǎn)信息、注意每一個(gè)塊最后節(jié)點(diǎn)next的處理
(1)如果i號(hào)塊不是最后一個(gè)完整快,那么next就是(i+2)*k - 1號(hào)節(jié)點(diǎn),也就是(i+1)號(hào)塊最后一個(gè)節(jié)點(diǎn)
(2)如果i號(hào)塊是最后一個(gè)塊,同樣有兩種情況
一、如果n%k==0,則說(shuō)明這是整個(gè)單聊表的最后一個(gè)節(jié)點(diǎn),輸出-1
二、如果n%k不等于0,則說(shuō)明這個(gè)完整快后面還有一點(diǎn)尾巴,那么這個(gè)完整塊的最后一個(gè)節(jié)點(diǎn)的next不是下一個(gè)塊的最后一個(gè),而是這個(gè)塊的第一個(gè),接下來(lái),從前往后輸出即可

learn && wrong:
1、存在無(wú)效節(jié)點(diǎn)的可能
2、反轉(zhuǎn)鏈表只改變節(jié)點(diǎn)的next地址,不改變本身地址,因此address和data是綁定的
3、%05d的輸出格式會(huì)讓-1出現(xiàn)錯(cuò)誤,所以-1要單獨(dú)輸出
4、給order排序很好
5、排序后輸出下一個(gè)節(jié)點(diǎn),就是【i+1】.adderss就很不錯(cuò)
*/

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100010;

struct Node{    //定義鏈表,步驟1
    int address,data,next;
    int order;  //節(jié)點(diǎn)在鏈表上的序號(hào),無(wú)效節(jié)點(diǎn)為maxn
}node[maxn];

bool cmp(Node a,Node b){
    return a.order < b.order;   //按order從小到大排序
}

int main()
{
    for(int i = 0;i <maxn;i++){ //初始化(步驟2)
        node[i].order = maxn;   //  初始化全部為無(wú)效節(jié)點(diǎn)
    }

    int begin, n, K, address;
    scanf("%d%d%d", &begin, &n, &K);    //起始地址,節(jié)點(diǎn)個(gè)數(shù)、步長(zhǎng)
    for(int i = 0;i < n;i++){
        scanf("%d",&address);
        scanf("%d%d", &node[address].data, &node[address].next);
        node[address].address = address;
    }

    int p = begin, count = 0;   //count計(jì)數(shù)有效節(jié)點(diǎn)的數(shù)目

    while(p != -1){ //遍歷鏈表找出單鏈表的所有效節(jié)點(diǎn)(步驟3)
        node[p].order = count++;    //節(jié)點(diǎn)在單鏈表中的序號(hào)
        p = node[p].next;  //下一個(gè)結(jié)點(diǎn)
    }

    sort(node, node + maxn, cmp);   //按單鏈表從頭到尾順序排列(步驟4)
    //有效節(jié)點(diǎn)為前count個(gè)節(jié)點(diǎn),為了下面書寫方便,因此把count賦給n
    n = count;
    //單鏈表已經(jīng)形成,下面是按題目要求的輸出(步驟5)
    for(int i = 0;i < n / K;i++){   //枚舉完整的n / K 塊
        for(int j = (i + 1) * K - 1;j < i * K;j--){ //第i塊倒著輸出
            printf("%05d %d %05d\n",    node[j].address, node[j].data, node[j - 1].address);
        }

        //下面是每一塊的最后一個(gè)結(jié)點(diǎn)的next地址的處理
        printf("%05d %d ", node[i * K].address, node[i * K].data);
        if(i < n / K - 1){  //如果不是最后一塊,就指向下一塊的最后一個(gè)結(jié)點(diǎn)
            printf("%05d\n", node[(i+2) * K - 1].address);
        }else{  //是最后一塊時(shí)
            if(n % K == 0){ //恰好是最后一個(gè)結(jié)點(diǎn),輸出-1
                printf("-1\n");
            }else{  //剩下的不完整塊按原先的順序輸出
                printf("%05d\n", node[(i + 1) * K].address);
                for(int i = n / K * K;i < n;i++){
                    printf("%05d %d", node[i].address, node[i].data);
                    if(n < -1){
                        printf("%05d\n",node[i+1].address);
                    }else{
                        printf("-1\n");
                    }
                }
            }
        }
    }
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容