【leetcode】:sort-list

题目:

Sort a linked list in O(n log n) time using constant space complexity.


解题思路:

这是一个单链表的排序问题 ;

内部要求的时间复杂度为 O(N*logN) ;空间复杂度为常数,也就是说不能新建结点的。

按照我们之前学的排序算法来看的话。

时间复杂度为O(N* logN)的算法都有:堆排序 、归并排序、快速排序(近似的)

在这里,堆排肯定是用不到了,因为堆排序是要使用的是下标的。 因此排除。

归并排序到时可以试试看:

当然、快速排序也是可以的,大家不要以为快排只有那么一种方式,在快排中有一种 前后指针法,就可以解决这个问题。

代码归并排序:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    //[left,right)
	//得到两个结点区间的中间节点 区间为【)
    ListNode* GetMidNode(ListNode* left,ListNode*  right)
    {
		//块慢指针法,一个走一步一个走两步
        ListNode*  fast = left;
        ListNode*  cur= left;
        while(fast != right&&fast->next!= right)
        {
            cur = cur->next;
            fast = fast->next;
            if(fast != right)
                fast= fast->next;
        }
        return  cur;    
    }
    //【)
	//归并排序
	//返回值为生成的有序的链表头结点
    ListNode* _MergeSort(ListNode*  start,ListNode* end)
    {
        //表示的只有一个结点
        if(start->next == end)
        {
			//将连接断开
            start->next = NULL;
            return  start;
        }
		//递归实现
        ListNode* mid  = GetMidNode(start,end);
        ListNode* left = _MergeSort(start,mid);
        ListNode* right= _MergeSort(mid,end);
		//此时left  、right 表示的就是两个   有序的链表
        ListNode*  ret = NULL;
        ListNode*  tail = NULL;
        while(left&&right)
        {
            if(left->val <= right->val)
            {
                if(tail)
                 {
                    tail->next = left;  
                    tail = left;
                }
                else
                {
                    ret = left;
                    tail = left;     
                }
                left = left->next;
            }
            else
            {
                if(tail)
                 {
                    tail->next = right;  
                    tail = right;
                }
                else
                {
                    ret = right;
                    tail = right;     
                }
                right = right->next;
            }
        }
        while(left)
        {
            if(tail)
            {
                tail->next = left;  
                tail = left;
            }
            else
            {
                ret = left;
                tail = left;     
            }
            left = left->next;
        }
        while(right)
        {    
            if(tail)
            {
                tail->next = right; 
                tail = right;
            }
            else
            {
                 ret = right;
                 tail = right;     
            }
            right = right->next;  
        }
           return ret;   
    }
    ListNode *sortList(ListNode *head) 
    {
    	if(head== NULL)
            return  NULL;
        if(head->next == NULL)
            return head;   
        return _MergeSort(head,NULL);
        
    }
};

代码快速排序(这段代码只实用于链表结点多的时候):

//用常数空间复杂度对O(n log n)时的链表排序。
//使用快速排序
//前后指针法
//【left,right】
void _sortList(ListNode*  left,ListNode*  right)
{
	if(left == right)
		return  ;
	int data = right->val;
	ListNode * cur = left; 
	ListNode * prev = NULL;
	while(cur != right)
	{
		if(cur->val <= data)
		{
			if(prev == NULL)
			{
				prev = left;
			}
			else
			{
				prev = prev->next;
			}
			swap(cur->val,prev->val); 
			cur = cur->next;
		}
		else
		{
			cur = cur->next;    
		}
	}
	_sortList(left,prev);
	if(prev == NULL)
	{
		prev = left;
	}
	else
	{
		prev = prev->next;
	}
	swap(cur->val,prev->val);
	if(prev != right)
	{
		_sortList(prev->next,right)  ;
	}
	
}
ListNode *sortList(ListNode *head) 
{
	if(head == NULL)
		return NULL;
	if(head->next == NULL)
		return  head;
	ListNode*  node = head; 
	while(node->next)
	{
		node = node->next;
	}
	_sortList(head,node);
	return  head;  
}


回答: 这个错误是因为在sort函数的第三个参数中引用了非静态成员函数,而在类定义中若不将成员函数声明为静态成员函数,会默认给成员函数添加一个this指针。而sort函数的第三个参数不允许有指针参数,所以会导致报错。解决这个问题的方法是将成员函数声明为静态成员函数,这样就不会添加this指针了。或者可以考虑将比较函数cmp定义为类外的普通函数,而不是成员函数。这样就可以解决该错误。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [[C++类静态成员函数]error: reference to non-static member function must be called](https://blog.csdn.net/qq_38337524/article/details/125084848)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [[Leetcode]错误:error: reference to non-static member function must be called](https://blog.csdn.net/weixin_46428351/article/details/123554510)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值