zoukankan      html  css  js  c++  java
  • 待字闺中之快排单向链表;leetcode之Sort List

    题目来源。待字闺中。原创@陈利人 。欢迎大家继续关注微信公众账号“待字闺中”

    分析:思路和数据的高速排序一样,都须要找到一个pivot元素、或者节点。

    然后将数组或者单向链表划分为两个部分。然后递归分别快排。

    针对数组进行快排的时候,交换交换不同位置的数值。在分而治之完毕之后,数据就是排序好的。那么单向链表是什么样的情况呢?除了交换节点值之外。是否有其它更好的方法呢?能够改动指针,不进行数值交换。这能够获取更高的效率。

    在改动指针的过程中。会产生新的头指针以及尾指针,要记录下来。在partition之后,要将小于pivot的的部分、pivot、以及大于pivot的部分又一次串起来成为一个singly linked list。

    在partition时。我们用最后的节点作为pivot。当我们扫描链表时,假设节点值大于pivot,将节点移到尾部之后;假设节点小于。保持不变。

    在递归排序时。我们先调用partition将pivot放到正确的为止并返回pivot,然后。递归左边。递归右边。最后在合成一个单链表。

    详细代码例如以下:

    #include <iostream>
    #include <map>
    #include <vector>
    #include <assert.h>
    using namespace std;
    
    struct node
    {
    	int data;
    	struct node* next;
    	node(int x):data(x),next(NULL){}
    };
    
    node* partition(node* start,node* end,node** newHead,node** newEnd)
    {
    	node* provit = end,*tmp = NULL,*pre = NULL;
    	while(start != provit)
    	{
    		if(start->data > provit->data)
    		{
    			tmp = start->next;
    			if(pre)pre->next = tmp;
    			start->next = NULL;
    			end->next = start;
    			end = start;
    			start = tmp;
    		}
    		else
    		{
    			if(*newHead == NULL)*newHead = start;
    			pre = start;
    			start = start->next;
    		}
    	}
    	if(*newHead == NULL)*newHead = provit;
    	*newEnd = end;
    	return provit;
    }
    node* GetTail(node* head)
    {
    	if(head == NULL)return NULL;
    	while(head->next != NULL)head = head->next;
    	return head;
    }
    node* QuickSort(node* head,node* end)
    {
    	if(head == NULL || head == end)return head;
    	node* newHead = NULL,*newEnd = NULL;//此处不能用二维指针。不然partition调用*newHead解引用时会出错
    	node* provit = partition(head,end,&newHead,&newEnd);
    	if(newHead != provit)
    	{
    		node* tmp = newHead;
    		while(tmp->next != provit)tmp = tmp->next;
    		tmp -> next = NULL;
    		newHead = QuickSort(newHead,tmp);
    		tmp = GetTail(newHead);
    		tmp->next = provit;
    	}
    	if(provit != newEnd)
    	{
    		provit->next= QuickSort(provit->next,newEnd);
    	}
    	return newHead;
    }
    void QuickSort(node** head)
    {
    	if(head == NULL)return;
    	*head = QuickSort(*head,GetTail(*head));
    }
    void printLink(node* head)
    {
    	while(head != NULL)
    	{
    		cout << head->data <<" ";
    		head = head->next;
    	}
    	cout << endl;
    }
    int main()
    {
    	int n,i,value;
    	node* head,*q;
    	cin >> n;
    	for(i=0;i<n;i++)
    	{
    		cin >> value;
    		if(i == 0)
    		{
    			head = new node(value);
    			q = head;
    		}
    		else
    		{
    			node* p = new node(value);
    			q->next = p;
    			q = p;
    		}
    	}
    	printLink(head);
    	QuickSort(&head);
    	printLink(head);
    	return 0;
    }


    leetcode之

    Sort List

     

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

    该题用上面的方法会超时,能够使用归并排序

    class Solution {
    public:
        ListNode *sortList(ListNode *head) 
        {
        	if(!head || !head->next)return head;
        	ListNode* fast = head -> next -> next;//至少有两个节点
        	ListNode* slow = head;
        	while(fast)
        	{
        		fast = fast->next;
        		slow = slow->next;
        		if(!fast)break;
        		fast = fast->next;
        	}
        	ListNode* p = slow -> next;
        	slow -> next = NULL;
        	ListNode* q = sortList(head);
        	p = sortList(p);
        	head = NULL;
        	ListNode* tail = NULL;
        	while(q && p)
        	{
        		if(q->val > p->val)
        		{
        			if(!head)head = tail = p;
        			else
        			{
        				tail->next = p;
        				tail = tail->next;
        			}
        			p = p->next;
        		}
        		else
        		{
        			if(!head)head = tail = q;
        			else
        			{
        				tail->next = q;
        				tail = tail->next;
        			}
        			q = q->next;
        		}
        	}
        	if(p)
        	{
        		if(!head)head = tail = p;
        		tail->next = p;
        	}
        	if(q)
        	{
        		if(!head)head = tail = q;
        		else tail->next = q;
        	}
        	return head;
        }
    };



  • 相关阅读:
    监控 | open-falcon | 安装
    日语 | 日本50音
    PXE | 开关机
    linux | 网卡驱动
    Linux——Centos 7 chmod命令
    Linux——Centos 7 ls命令
    Linux——Centos 7 passwd命令
    Linux——Centos 7 账户管理命令(用户组篇)groupadd groupmod groupdel
    Linux——Centos 7 账户管理命令(用户篇)useradd usermod userdel
    Linux——Centos 7 diff命令
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/6693286.html
Copyright © 2011-2022 走看看