单链表排序

单链表排序不同于一般的排序,一般的排序支持随机读取,但是单链表不支持随机读取,要一点一点从头开始遍历,而且在排序时要特别注重指针的操作。在这里,介绍几种应用于单链表的排序方法。

首先,做一些提前的准备工作,创建链表和打印链表。
创建链表:

struct ListNode
{
    int val;
    ListNode* next;
};

void InsertNode(ListNode* &head, int value)
{
    if (head == NULL)
    {
        head = (ListNode *)malloc(sizeof(ListNode));
        if (head == NULL)
        {
            cout<<"malloc failed";
            return;
        }
        else
        {
            head->val = value;
            head->next = NULL;
        }
    }
    else
    {
        ListNode *temp = (ListNode *)malloc(sizeof(ListNode));
        if (temp == NULL)
        {
            cout<<"malloc failed";
            return;
        }
        else
        {
            temp->val = value;
            temp->next = head;
            head = temp;
        }
    }
    return;
}
void Insert(int n,ListNode* &head)
{
    srand((unsigned)time(NULL));         //初始化随机数  
    for (int i = 0; i < n; i++)
        InsertNode(head, rand());
    ListNode *p = (ListNode *)malloc(sizeof(ListNode));
    p->next = head;
    head = p;
    cout<<"所有的随机数为: ";
    p = head->next;    //输出测试  
    while (p)
    {
        //printf("%d  ", p->val);
        cout << p->val << " ";
        p = p->next;
    }
    cout << endl;
    cout << endl;
    return;
}

打印链表:

void printlist(ListNode* head)
{
    ListNode* node = head->next;
    while (node)
    {
        cout << node->val << " ";
        node = node->next;
    }
    cout << endl;
}

主函数:

int main()
{
    ListNode* head = NULL;
    Insert(20, head);
    select_sort(head);//这里的函数可改变
    printlist(head);
    system("pause");
    return 0;
}

下面进入正题:
第一个算法:选择排序算法在单链表的应用。
选择排序算法的基本思想是:将待排序数组分成有序区和无序区,初始化时整个数组都是无序区,每次从无序区中选择最小的数加到有序区的后面,直到无序区只剩下最后一个数为止。

void select_sort(ListNode* &head)
{
    //sorted是已排序数组的末尾,unsorted是未排序数组的开头,min指向最小的节点
    //premin指向min前面一个节点
    ListNode* sorted, *unsorted, *min,*premin;
    sorted = NULL;
    unsorted = head;
    min = NULL;

    while (unsorted->next)
    {
        min = unsorted;
        ListNode* temp = unsorted->next;

        while (temp)
        {
            if (temp->val < min->val)
                min = temp;
            temp = temp->next;
        }

        if (min == unsorted)
            sorted = unsorted;
        else
        {
            //premin是为了保证链表不断开,min之前的结点指向min之后的结点
            premin = unsorted;
            while (premin->next != min)
                premin = premin->next;
            premin->next = min->next;

            if (sorted == NULL)
            {
                min->next = head;
                head = sorted = min;
            }
            else
            {
                sorted->next = min;
                min->next = unsorted;
                sorted = min;
            }
        }
        unsorted = sorted->next;
    }
}

输出:这里写图片描述

算法二:插入算法。
直接插入算法:将待排序数组分成有序区和无序区,初始化时认为左边第一个元素有序,每次将无序区的首个元素依次与有序区的数比较,将其插入到有序区合适的位置,直到无序区元素个数为0

void insert_sort(ListNode* head)
{
    if (head == NULL)
        return;
    ListNode *sorted,*unsorted;//划分有序区和无序区
    sorted = NULL;
    unsorted = head;

    while (unsorted)
    {
        ListNode* prenode = NULL;
        ListNode* node = head;
        while (node && node != unsorted &&node->val < unsorted->val)
        {
            prenode = node;
            node = node->next;
        }


        if (node == unsorted)
        {
            sorted = unsorted;
            //unsorted = unsorted->next;
        }
        else
        {
            sorted->next = unsorted->next;
            prenode->next = unsorted;
            unsorted->next = node;
            //unsorted = sorted->next;
        }
        unsorted = sorted->next;
    }
}

输出:这里写图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值