解题思路:

注意事项:

参考代码:

#include <stdio.h>

#include <stdlib.h>

#include <math.h>


typedef struct be {

    int value;//数据

    //左指针,右指针,伙伴指针

    struct be *left, *right, *huo;

    char runOstop;//0,跳跃,1停止

} TU;


// 函数声明

void isRun(TU *);

void output(TU*, int);

void jumpR(TU*);

TU* findRoot(TU*);

TU* mergeSort(TU*);

TU* split(TU*);

TU* merge(TU* , TU*);

int getListLength(TU*);


int main(int argc, char** argv) {

    int n;

    scanf("%d", &n);

    TU *head = (TU*)calloc(n, sizeof(TU));


    // 输入数据

    for (int i = 0; i < n; i++) {

        scanf("%d", &head[i].value);

        head[i].runOstop = 0;

    }


    // 将数组转换为链表并排序

    TU *list = head;

    for (int i = 1; i < n; i++) {

        list->right = head+i;

        head[i].left = list;

        list = list->right;

    }

    list->right = NULL;

    head[0].left = NULL;


    // 归并排序

    TU *sorted = mergeSort(head);


    // 重新建立循环连接

    TU *last = sorted;

    while (last->right != NULL) {

        last = last->right;

    }

    last->right = sorted;

    sorted->left = last;


    // 处理排序后的链表

    isRun(sorted);

    jumpR(sorted);


    // 输出结果

    output(head, n);

    free(head);

    return 0;

}


// 归并排序实现

TU* mergeSort(TU* head) {

    if (!head || !head->right) return head;


    TU* second = split(head);


    head = mergeSort(head);

    second = mergeSort(second);


    return merge(head, second);

}


// 分割链表

TU* split(TU* head) {

    TU* fast = head;

    TU* slow = head;


    while (fast->right && fast->right->right) {

        fast = fast->right->right;

        slow = slow->right;

    }


    TU* temp = slow->right;

    slow->right = NULL;

    if (temp) temp->left = NULL;

    return temp;

}


// 合并两个有序链表

TU* merge(TU* first, TU* second) {

    if (!first) return second;

    if (!second) return first;


    if (first->value <= second->value) {

        first->right = merge(first->right, second);

        first->right->left = first;

        first->left = NULL;

        return first;

    } else {

        second->right = merge(first, second->right);

        second->right->left = second;

        second->left = NULL;

        return second;

    }

}


// 输出函数

void output(TU *a, int n) {

    for (int i = 0; i < n; i++)

        printf("%d ", a[i].value);

}


// 确定每个节点的伙伴

void isRun(TU *st) {

    TU *p = st;

    do {

        int a = abs(p->value - p->left->value);

        int b = abs(p->right->value - p->value);

        p->huo = (a <= b) ? p->left : p->right;

        p = p->right;

    } while (p != st);

}


// 查找根节点

TU* findRoot(TU* node) {

    TU *root = node;

    while (root->huo->huo != root)

        root = root->huo;

    TU *current = node;

    while (current != root) {

        TU *next = current->huo;

        current->huo = root;

        current = next;

    }

    return root;

}


// 处理跳跃逻辑

void jumpR(TU* st) {

    TU *current = st;

    do {

        if (current->runOstop) {

            current = current->right;

            continue;

        }


        TU *peer = current->huo;

        if (peer->huo == current) {

            int x = current->value, y = peer->value;


            current->value = peer->value = (x + y) / 2;

            current->runOstop = peer->runOstop = 1;

        }

        current = current->right;

    } while (current != st);


    current = st;

    do {

        if (!current->runOstop) {

            TU *root = findRoot(current);

            current->value = root->value;

            current->runOstop = 1;

        }

        current = current->right;

    } while (current != st);

}

点赞(0)
 

0.0分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论