单链表的归并排序

由于单链表没有指向前一个节点的指针,而归并排序排序不需要对前一个节点进行操作,所以归并排序算法很适合用来对单链表排序,代码如下:

#include "stdafx.h"
#include <iostream>
using namespace std;
  struct ListNode {
      int val;
      ListNode *next;
      ListNode(int x) : val(x), next(NULL) {}
  };
 
class Solution {
public:
    ListNode *sortList(ListNode *head) {
        if(head==NULL || head->next==NULL)
            return head;
        ListNode* fast=head,*slow=head;
        while(fast->next!=NULL &&fast->next->next!=NULL) //归并排序,需要用到中间节点,快慢指针是求链表中间节点常用的方法
        {
            fast=fast->next->next;
            slow=slow->next;
        }
        fast=slow;
        slow=slow->next;
        fast->next=NULL;
        ListNode *leftList=sortList(head);
        ListNode *rightList=sortList(slow);
        return mergeInsert(leftList,rightList);
    }
    ListNode *mergeInsert(ListNode *leftList,ListNode *rightList)
    {
        ListNode tmpNode(-1);
        ListNode *pTemp;
        for(pTemp=&tmpNode;leftList!=nullptr && rightList!=nullptr;pTemp=pTemp->next)
        {
            if(leftList->val<=rightList->val)
            {
                pTemp->next=leftList;
                leftList=leftList->next;
            }
            else
            {
                 pTemp->next=rightList;
                rightList=rightList->next;
            }
        }
        while(leftList!=nullptr)
        {
            pTemp->next=leftList;
            pTemp=pTemp->next;
            leftList=leftList->next;
        }
        while(rightList!=nullptr)
        {
            pTemp->next=rightList;
            pTemp=pTemp->next;
            rightList=rightList->next;
        }
        return tmpNode.next;
    }
};


int _tmain(int argc, _TCHAR* argv[])
{
	struct ListNode head(-1);
	int inputNodeNum=0;
	struct ListNode *pHead=&head;
	Solution sln;
	while (cin>>inputNodeNum)
	{
		int valTmp=0;
		for (int i=0;i<inputNodeNum;++i)
		{
			cin>>valTmp;
			pHead->next=new struct ListNode(valTmp);
			pHead=pHead->next;
		}
		struct ListNode* pResult=sln.sortList(head.next);
		struct ListNode* pTmpResult=pResult;
		while(pTmpResult!=nullptr)
		{
			cout<<pTmpResult->val<<"  ";
			pTmpResult=pTmpResult->next;
		}
		while(pResult!=nullptr)
		{
			pTmpResult=pResult;
			pResult=pResult->next;
			delete pTmpResult;
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单链表归并排序的C语言实现步骤如下: 1. 定义单链表结构体和归并排序函数 2. 实现归并排序函数,其中包括以下步骤: a. 如果链表为空或只有一个节点,直接返回 b. 使用快慢指针将链表分成两个子链表 c. 递归调用归并排序函数对两个子链表进行排序 d. 合并两个已排序的子链表 下面是单链表归并排序的C语言代码实现: ``` #include <stdio.h> #include <stdlib.h> // 定义单链表结构体 typedef struct ListNode { int val; struct ListNode *next; } ListNode; // 归并排序函数 ListNode* mergeSortList(ListNode* head) { if (head == NULL || head->next == NULL) { return head; } // 使用快慢指针将链表分成两个子链表 ListNode *slow = head, *fast = head->next; while (fast != NULL && fast->next != NULL) { slow = slow->next; fast = fast->next->next; } ListNode *mid = slow->next; slow->next = NULL; // 递归调用归并排序函数对两个子链表进行排序 ListNode *left = mergeSortList(head); ListNode *right = mergeSortList(mid); // 合并两个已排序的子链表 ListNode *dummy = (ListNode*)malloc(sizeof(ListNode)); ListNode *cur = dummy; while (left != NULL && right != NULL) { if (left->val < right->val) { cur->next = left; left = left->next; } else { cur->next = right; right = right->next; } cur = cur->next; } cur->next = (left != NULL) ? left : right; ListNode *newHead = dummy->next; free(dummy); return newHead; } // 测试代码 int main() { // 创建链表 ListNode *head = (ListNode*)malloc(sizeof(ListNode)); head->val = 4; head->next = (ListNode*)malloc(sizeof(ListNode)); head->next->val = 2; head->next->next = (ListNode*)malloc(sizeof(ListNode)); head->next->next->val = 1; head->next->next->next = (ListNode*)malloc(sizeof(ListNode)); head->next->next->next->val = 3; head->next->next->next->next = NULL; // 归并排序 ListNode *newHead = mergeSortList(head); // 输出排序后的链表 while (newHead != NULL) { printf("%d ", newHead->val); newHead = newHead->next; } printf("\n"); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值