📜  双向链表上快速排序的 C++ 程序(1)

📅  最后修改于: 2023-12-03 15:22:51.732000             🧑  作者: Mango

双向链表上快速排序的 C++ 程序

快速排序是一种常用的排序算法,其核心思想是选择一个基准元素,将待排序序列分成两个部分,一部分小于基准元素,一部分大于基准元素,再对分割出来的两个部分分别进行快速排序。这个过程可以使用递归实现,直到待排序序列只剩下一个元素,即排序完成。

双向链表(Doubly Linked List)是一种链表结构,每个节点包含一个指向前驱节点的指针和一个指向后继节点的指针。双向链表可以支持双向遍历,比单向链表更加灵活。

在本文中,我们将介绍如何在双向链表上使用快速排序算法进行排序,并给出相应的 C++ 程序。

算法思路

下面是双向链表上快速排序的具体算法:

  1. 首先选择一个基准元素 pivot;
  2. 从链表头开始遍历,将链表分成小于基准元素的链表 A 和大于等于基准元素的链表 B;
  3. 对 A 和 B 分别进行递归排序(此处使用快速排序算法);
  4. 最终将 A、pivot 和 B 拼接在一起,即完成排序。

算法流程图如下所示:

graph TD;
  subgraph 选择基准元素
    start((start)) --> 随机选择一个元素作为基准元素
  end;
  subgraph 分割链表
    遍历链表 --> 小于基准元素的链表
    遍历链表 --> 大于等于基准元素的链表
  end;
  subgraph 递归排序
    小于基准元素的链表 -- 递归排序 --> 分别排序
    大于等于基准元素的链表 -- 递归排序 --> 分别排序
  end;
  subgraph 合并链表
    小于基准元素的链表 --> pivot
    pivot --> 大于等于基准元素的链表
    subgraph 拼接链表
      小于基准元素的链表 --> B
      pivot --> B
    end;
    subgraph 拼接链表
      A --> pivot
      A --> 大于等于基准元素的链表
    end;
  end;
C++ 程序实现

下面是在双向链表上实现快速排序的 C++ 程序:

#include <iostream>

using namespace std;

// 定义双向链表节点的结构体
struct Node {
    int val;
    Node *prev, *next;
    Node(int x) : val(x), prev(NULL), next(NULL) {}
};

// 定义双向链表的类
class DoublyLinkedList {
public:
    Node *head, *tail;
    DoublyLinkedList() : head(NULL), tail(NULL) {}

    // 在链表尾部添加一个节点
    void append(int val) {
        Node *node = new Node(val);
        if (head == NULL) {
            head = node;
            tail = node;
        } else {
            tail->next = node;
            node->prev = tail;
            tail = node;
        }
    }

    // 快速排序算法
    Node* quickSort(Node *l, Node *r) {
        if (l == NULL || r == NULL || l == r) {
            return l;
        }
        Node *pivot = partition(l, r);
        if (pivot != l) {
            pivot->prev = quickSort(l, pivot->prev);
            pivot->next = quickSort(pivot->next, r);
        } else {
            pivot->next = quickSort(pivot->next, r);
        }
        return pivot;
    }

    // 分割链表算法
    Node* partition(Node *l, Node *r) {
        int pivot = l->val;
        Node *i = l, *j = r;
        while (i != j) {
            while (i != j && i->val < pivot) i = i->next;
            while (i != j && j->val >= pivot) j = j->prev;
            if (i != j) swap(i->val, j->val);
        }
        swap(l->val, j->val);
        return j;
    }

    // 输出链表
    void print() {
        Node *cur = head;
        while (cur != NULL) {
            cout << cur->val << " ";
            cur = cur->next;
        }
    }
};

int main() {
    DoublyLinkedList dll;
    dll.append(4);
    dll.append(3);
    dll.append(5);
    dll.append(1);
    dll.append(2);
    cout << "Original List: " << endl;
    dll.print();
    cout << endl;
    dll.head = dll.quickSort(dll.head, dll.tail);
    cout << "Sorted List: " << endl;
    dll.print();
    cout << endl;
    return 0;
}

该程序定义了一个 DoublyLinkedList 类来实现双向链表,其中包括 append、quickSort、partition 和 print 等方法。其中,quickSort 和 partition 方法实现快速排序算法的核心部分。

总结

本文介绍了一种在双向链表上实现快速排序的算法,并提供了相应的 C++ 程序实现。双向链表上的快速排序可以通过递归实现,每次将链表分成小于基准元素和大于等于基准元素两个链表,再对这两个链表分别进行快速排序,最终将这三个部分拼接在一起即可得到排序后的双向链表。该算法时间复杂度为 O(nlogn)。