当前位置: 首页 > article >正文

双向链表的快速排序函数

 链表的节点作为快速排序的元素,通过节点的指针进行操作,而不是通过数组索引 

public void quickSort(int[] arr, int left, int right){
        if(left < right){
            int pos = partition(arr, left, right);
            quickSort(arr, left, pos - 1);
            quickSort(arr, pos + 1, right);
        }
    }
public int partition(int[] arr, int left, int right){
        int base = arr[left];
        while(left < right){
            while(left < right && arr[right] >= base){
                right--;
            }
            arr[left] = arr[right];
            while(left < right && arr[left] <= base){
                left++;
            }
            arr[right] = arr[left];       
        }
        arr[left] = base;
        return left;
    }
}

思路

  1. 选基准:选择链表的最后一个节点作为基准值。
  2. 初始化指针low 指向链表的第一个节点,high 指向链表的最后一个节点。
  3. 划分:(遍历链表,将小于基准值的节点移动到基准值左侧,将大于基准值的节点移动到基准值右侧)
    • 指针 i j遍历链表,i 从 low 的前节点开始,j 从 low 开始。
    • 如果 j 指向的节点数据小于基准值,则 i 向后移一位,并交换 i 和 j 指向节点数据。
    • 移动 j,直到 j 和 high 相邻。
    • 交换 i 的下一个节点和 high 的数据。
  4. 递归排序:(对基准值左侧和右侧的子链表分别进行快速排序)
    • 对 low 到 i 的前一个节点进行快速排序。
    • 对 i 的下一个节点到 high 进行快速排序。

代码

// 节点结构体
typedef struct DoublyLinkedListNode {
    int data;
    struct DoublyLinkedListNode *prev;
    struct DoublyLinkedListNode *next;
} DoublyLinkedListNode;

// 创建节点
DoublyLinkedListNode* createNode(int data) {
    DoublyLinkedListNode* newNode = (DoublyLinkedListNode*)malloc(sizeof(DoublyLinkedListNode));
    newNode->data = data;
    newNode->prev = NULL;
    newNode->next = NULL;
    return newNode;
}

// 尾插
void appendNode(DoublyLinkedListNode** head, int data) {
    DoublyLinkedListNode* newNode = createNode(data);
    if (*head == NULL) {// 如果链表为空
        *head = newNode; // 新节点成为头节点
        return;
    }
    DoublyLinkedListNode* temp = *head;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = newNode;
    newNode->prev = temp;
}

// 交换节点的数据
void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 获取链表最后节点
DoublyLinkedListNode* getLastNode(DoublyLinkedListNode* head) {
    while (head && head->next) {
        head = head->next;
    }
    return head;
}

// 快速排序的划分函数
DoublyLinkedListNode* partition(DoublyLinkedListNode* low, DoublyLinkedListNode* high) {
    int base = high->data;
    DoublyLinkedListNode* i = low->prev;

    for (DoublyLinkedListNode* j = low; j != high; j = j->next) {
        if (j->data <=base) {// 如果当前节点数据小于等于基准值
            i = (i == NULL) ? low : i->next;
            swap(&(i->data), &(j->data));
        }
    }
    i = (i == NULL) ? low : i->next;
    swap(&(i->data), &(high->data));
    return i;//划分后的基准位置
}

// 快速排序函数
void quickSort(DoublyLinkedListNode* low, DoublyLinkedListNode* high) {
    if (high != NULL && low != high && low != high->next) { //至少有两个节点
        DoublyLinkedListNode* p = partition(low, high); // 划分链表
        quickSort(low, p->prev);// 递归排序左子链表
        quickSort(p->next, high);
    }
}

// 打印链表
void printList(DoublyLinkedListNode* head) {
    while (head != NULL) {
        printf("%d ", head->data);
        head = head->next;
    }
    printf("\n");
}

int main() {
    DoublyLinkedListNode* head = NULL;// 初始化链表头指针
    appendNode(&head, 4);
    appendNode(&head, 2);
    appendNode(&head, 5);
    appendNode(&head, 3);
    appendNode(&head, 1);

    printf("排序前: ");
    printList(head);

    quickSort(head, getLastNode(head));

    printf("排序后: ");
    printList(head);

    return 0;
}

运行结果 

 


http://www.kler.cn/a/529617.html

相关文章:

  • CSS(快速入门)
  • 【自然语言处理(NLP)】基于Transformer架构的预训练语言模型:BERT 训练之数据集处理、训练代码实现
  • openEuler系统磁盘管理方法
  • Vue 与 Electron 结合开发桌面应用
  • php的使用及 phpstorm环境部署
  • Leetcode::81. 搜索旋转排序数组 II
  • 猴子吃桃问题
  • DeepSeek V3 vs R1:大模型技术路径的“瑞士军刀“与“手术刀“进化
  • BUUCTF_[安洵杯 2019]easy_web(preg_match绕过/MD5强碰撞绕过/代码审计)
  • 一文了解DeepSeek
  • Linux学习之DNS基础服务器搭建
  • Java死锁问题
  • OpenAI深夜反击:o3-mini免费上线,能否撼动DeepSeek的地位?
  • 青少年编程与数学 02-008 Pyhon语言编程基础 14课题、创建函数
  • C++ Primer 标准库类型string
  • C#面试常考随笔10:C#中有哪些常用的容器类,各有什么特点?
  • 如何使用SliverGrid组件
  • 【含文档+PPT+源码】基于微信小程序连锁药店商城
  • 2025年02月01日Github流行趋势
  • AI赋能医疗信息化与医保新政双轮驱动:医药生物行业投资机遇深度解析
  • MySQL存储过程和存储函数_mysql 存储过 call proc_stat_data(3,null)
  • C++【iostream】数据库的部分函数功能介绍
  • docker部署SpringBoot项目简单流程
  • Kotlin/Js Kotlin 编译为 JS (尝试)
  • 【产品经理学习案例——AI翻译棒出海业务】
  • C# List 列表综合运用实例⁓Hypak原始数据处理编程小结