C++程序 对0、1、2形式的链表进行排序

C++程序 对0、1、2形式的链表进行排序

C++中,链表是一种常见的数据结构,它可以实现动态的数据存储。对于0、1、2形式的链表,我们可以采用不同的排序算法进行排序,本文将介绍如何使用C++编写程序,对0、1、2形式的链表进行排序。

一、链表的定义和创建

链表是一种非线性数据结构,它由节点组成,每个节点包含两个部分:数据域和指针域。指针域指向下一个节点,最后一个节点的指针域指向NULL。

定义链表节点的结构体如下:

//链表的节点
struct ListNode{
    int val; //数据域
    ListNode *next; //指针域
    ListNode(int x) : val(x), next(NULL) {} //构造函数
};

创建链表的方法很多,本文介绍两种方法:

方法一:头插法创建链表

头插法是指,在链表头插入节点,插入顺序和数据顺序相反,即后插入的数据在前面。具体实现如下:

//头插法创建链表
ListNode* createList(vector<int> &nums){
    ListNode *head = new ListNode(-1);
    for(int i = 0; i < nums.size(); i++){
        ListNode *node = new ListNode(nums[i]);
        node->next = head->next;
        head->next = node;
    }
    return head->next;
}

例如,要创建一个链表1->2->3->4,代码如下:

vector<int> nums = {1,2,3,4};
ListNode *head = createList(nums);

方法二:尾插法创建链表

尾插法是指,在链表尾插入节点,插入顺序和数据顺序相同,即后插入的数据在末尾。具体实现如下:

//尾插法创建链表
ListNode* createList(vector<int> &nums){
    ListNode *head = new ListNode(-1);
    ListNode *tail = head;
    for(int i = 0; i < nums.size(); i++){
        ListNode *node = new ListNode(nums[i]);
        tail->next = node;
        tail = tail->next;
    }
    return head->next;
}

例如,要创建一个链表1->2->3->4,代码如下:

vector<int> nums = {1,2,3,4};
ListNode *head = createList(nums);

二、对0、1、2形式的链表进行排序

方法一:计数排序

计数排序是一种简单且高效的排序算法,在本例中可以用来对0、1、2形式的链表进行排序。

计数排序的思路是,先统计序列中0、1、2出现的次数,然后按照次数的顺序依次输出每个元素,即可完成排序。

具体实现如下:

ListNode* sortList(ListNode* head) {
    int count[3] = {0,0,0};
    ListNode *p = head;
    while(p){
        count[p->val]++;
        p = p->next;
    }
    p = head;
    for(int i = 0; i < 3; i++){
        for(int j = 0; j < count[i]; j++){
            p->val = i;
            p = p->next;
        }
    }
    return head;
}

例如,要对链表1->0->2->0->1进行排序,代码如下:

vector<int> nums = {1,0,2,0,1};
ListNode *head = createList(nums);
head = sortList(head);

方法二:快速排序

快速排序是一种常用的排序算法,它的核心思想是分治法。在本例中,可以用快速排序来对链表进行排序。

快速排序的思路是,在序列中选择一个元素作为基准值,将序列划分为两部分,一部分比基准值小,一部分比基准值大,然后对这两部分分别递归进行快速排序,最终整个序列就被排序了。

具体实现如下:

//获取链表的中间节点
ListNode* getMidNode(ListNode* head){
    ListNode *slow = head;
    ListNode *fast = head->next;
    while(fast != NULL && fast->next != NULL){
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}

//合并两个有序链表
ListNode* merge(ListNode* left, ListNode* right){
    ListNode *merged = new ListNode(-1);
    ListNode *p = merged;
    while(left && right){
        if(left->val < right->val){
            p->next = left;
            left = left->next;
        }
        else{
            p->next = right;
            right = right->next;
        }
        p = p->next;
    }
    if(left){
        p->next = left;
    }
    if(right){
        p->next = right;
    }
    return merged->next;
}

//快速排序
ListNode* quickSort(ListNode* head){
    if(head == NULL || head->next == NULL){
        return head;
    }
    //选择第一个节点作为基准值
    ListNode *pivot = head;
    head = head->next;
    pivot->next = NULL;
    //将序列划分为两部分
    ListNode *left = new ListNode(-1);
    ListNode *right = new ListNode(-1);
    ListNode *p = head;
    ListNode *l = left;
    ListNode *r = right;
    while(p){
        if(p->val < pivot->val){
            l->next = p;
            l = l->next;
        }
        else{
            r->next = p;
            r = r->next;
        }
        p = p->next;
    }
    //递归排序左右两部分
    left = quickSort(left->next);
    right = quickSort(right->next);
    //合并排好序的链表
    ListNode *merged = merge(left, right);
    //连接基准值节点
    p = merged;
    while(p->next){
        p = p->next;
    }
    p->next = pivot;
    pivot->next = merge(left, right);
    return merged;
}

例如,要对链表1->0->2->0->1进行排序,代码如下:

vector<int> nums = {1,0,2,0,1};
ListNode *head = createList(nums);
head = quickSort(head);

结论

本文介绍了两种方法来对0、1、2形式的链表进行排序:计数排序和快速排序。通过实现这两种算法,可以更好地理解链表和排序算法的基本原理。需要注意的是,在实际应用中,不同的排序算法可能有不同的优缺点,需要根据实际情况选择合适的算法。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

C++ 示例