方法一:递归实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if( l1 == nullptr )
{
return l2;
}
else if( l2 == nullptr )
{
return l1;
}
ListNode* pMergeHead = nullptr;
if( l1->val < l2->val )
{
pMergeHead = l1;
pMergeHead->next = mergeTwoLists( l1->next, l2 );
}
else
{
pMergeHead = l2;
pMergeHead->next = mergeTwoLists( l1, l2->next );
}
return pMergeHead;
}
};
方法二:归并排序思想
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
//归并排序中的思想
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1 == NULL){
return l2;
}
if(l2 == NULL){
return l1;
}
ListNode* head = new ListNode(0);
ListNode* node = head;
while(l1 != NULL && l2 != NULL){
if(l1->val > l2->val){
node->next = l2;
l2 = l2->next;
}
else{
node->next = l1;
l1 = l1->next;
}
node = node->next;
}
if(l1 == NULL){
node ->next = l2;
}
if(l2 == NULL){
node->next = l1;
}
return head->next;
}
};
附:排序算法
归并排序
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
merge(nums,0,nums.size()-1);
return nums;
}
void merge(vector<int>& nums,int left, int right)
{
if(left>=right)
return;
else
{
int mid = (left + right) / 2;
merge(nums,left,mid);
merge(nums,mid+1,right);
merge_sort(nums,mid,left,right);
}
}
void merge_sort(vector<int>& nums,int mid,int l, int r)
{
int left_size = mid -l + 1;
int right_size = r - mid;
int left[left_size];
int right[right_size];
int i,j,k;
//把nums数组里面的内容填充到左右两个数组里面去
for(i = l; i <=mid ; i++)
{
left[i-l] = nums[i];
}
for(i = mid+1; i <=r ; i++)
{
right[i-(mid+1)] = nums[i];
}
//左右两个数组进行比较然后重新填充会nums中
i = 0; j = 0; k = l;
while( i < left_size && j < right_size)
{
if(left[i] > right[j])
{
nums[k]=right[j];
j++;
k++;
}
else
{
nums[k] = left[i];
i++;
k++;
}
}
while( i < left_size)
{
nums[k] = left[i];
i++;
k++;
}
while( j < right_size)
{
nums[k] = right[j];
j++;
k++;
}
}
};
链表排序
这一题就是要用到归并排序的思想,并且最后一步就是用到合并已经排序的链表。
思路步骤:
1、用快慢指针找到链表的中点。
2、递归分治切分链表
3、再排序链表
和递归排序的思想一样,并且链表的归并是不需要开辟额外空间的,所以是常数级空间复杂度。
class Solution {
public:
ListNode* findMidNode(ListNode* head)
{
ListNode* lowNode = head; //慢指针
ListNode* fastNode = head->next; // 快指针
while( fastNode != nullptr && fastNode->next != nullptr)
{
lowNode = lowNode->next;
fastNode = fastNode->next->next;
}
return lowNode;
}
//剑指offer25题,合并两个排序的数组
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1 == NULL){
return l2;
}
if(l2 == NULL){
return l1;
}
ListNode* head = new ListNode(0);
ListNode* node = head;
while(l1 != NULL && l2 != NULL){
if(l1->val > l2->val){
node->next = l2;
l2 = l2->next;
}
else{
node->next = l1;
l1 = l1->next;
}
node = node->next;
}
if(l1 == NULL){
node ->next = l2;
}
if(l2 == NULL){
node->next = l1;
}
return head->next;
}
ListNode* sortList(ListNode* head) {
//这里就是归并排序的思想了
if(head==nullptr || head->next == nullptr)
return head;
ListNode* middle = findMidNode(head);
//先对后面的操作,再对前面的,因为链表是连接的,得从中点出断开,区分左右两个链表
ListNode* right = sortList(middle->next);
middle->next = nullptr;
ListNode* left = sortList(head);
return mergeTwoLists(left, right);
}
};