LeetCode 148-排序链表

45 篇文章 1 订阅
24 篇文章 0 订阅

LeetCode 148.排序链表 题目链接

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

解题思路:我采用的是一种取巧的方式,定义了一条和链表等长的数组,将每个结点的 val 值存储在数组中,用快速排序法将数组排序后,再一一赋值给链表。
时间复杂度肯定是 O(nlogn) 但是空间复杂度就大了,因为定义了等长的数组,在链表过长的情况下很有可能找不到满足大小的内存块,可以尝试普遍采用的 归并排序方法,社区解答参考
代码如下,没有采用 C 语言 stdlib.h 库中的 qsort 方法而且使用了 三数中值快速排序法。(因为 qsort 适应不同大小的数据,增加了程序的时间复杂度)

#include <malloc.h>
void insertSort(int *nums, int n)
{
	//int *temps = (int *)malloc(sizeof(int )*n);
	/*
	把数据分成两个部分一部分是有序的另一部分是无序的,
	每次把无序数列中的第一个数插入到有序数列中按顺序排列的位置
	*/
	int j = 0, i = 0;
	for (; i < n - 1; i++)
	{
		int value = *(nums + i + 1);
		for (j = i; j >= 0; )
		{
			if (*(nums + j) > value)
			{
				*(nums + j + 1) = *(nums + j);
				j--;
			}
			else
				break;
		}
		*(nums + j + 1) = value;
	}
}
void swap(int *a, int *b)
{
	int c;
	c = *a;
	*a = *b;
	*b = c;
}


int median3(int a[], int left, int right)	//获得枢纽元,使用三数中值法
{
	int center = (left + right) / 2;

	if (a[left]>a[center])
		swap(&a[left], &a[center]);
	if (a[left]>a[right])
		swap(&a[left], &a[right]);
	if (a[center]>a[right])
		swap(&a[center], &a[right]);
	swap(&a[center], &a[right - 1]);	//将枢纽元放到数组最后
	return a[right - 1];
}

void Qsort(int a[], int left, int right)
{
	int i, j;
	int pivot;

	if ((left + 3) <= right)
	{
		pivot = median3(a, left, right);
		i = left, j = right - 1;
		for (;;)
		{
			while (a[++i]<pivot) {}	//因为第一次是a[i]小于pivot,a[j]是大于pivot,所以用++i
			while (a[--j]>pivot) {}
			if (i<j)
				swap(&a[i], &a[j]);	//出现等于的情况,交换,平均分配到子数组中
			else
				break;
		}
		swap(&a[i], &a[right - 1]);
		Qsort(a, left, i - 1);	//在i的位置之前,所有的元素都小于它,在i之后,所有的元素都大于它,所以A[i]的位置不需要变
		Qsort(a, i + 1, right);
	}
	else	//当数组很小的时候,只做插入排序,从而退出递归,不需要等到数组长度等于1的时候,因为对于小数组来说,插入排序好过快速排序
		insertSort(a + left, right - left + 1);	//插入排序例程在前面的文章中已经实现了
}
void quickSort(int a[], int length)
{
	Qsort(a, 0, length - 1);
}
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
	int min = nums1Size<nums2Size ? nums1Size : nums2Size;
	*returnSize = 0;
	int *tempNums = (int *)malloc(min*sizeof(int));
	if (min == nums1Size)
	{
		quickSort(nums1, nums1Size); quickSort(nums2, nums2Size);
		int i = 0, k = 0;
		while (i != min)
		{
			if (nums1[i] == nums2[k])
			{
				tempNums[*returnSize] = nums1[i];
				i++; k++; (*returnSize)++;

				//printf("%d  ",*returnSize);
			}
			else if (nums1[i]>nums2[k])
				k++;
			else if (nums1[i] < nums2[k])
				i++;
			if (k == nums2Size)
				break;
		}
	}
	else
	{
		tempNums = intersect(nums2, nums2Size, nums1, nums1Size, returnSize);
	}
	return tempNums;
}
/// 题目限定时间复杂度为 O(nlogn) 或 O(n),采用快速排序。
/// 先定义一个和链表等长的数组,将每个链表的每个值都赋给数组
/// 对数组使用快速排序,再一一赋值给链表
struct ListNode* sortList(struct ListNode* head) {
	int count = 0, i = 0;
	struct ListNode* p = head;
	//p = head->next;
	while (p != NULL)
	{
		count++;
		p = p->next;
	}
	if (count == 1 || count == 0)
		return head;
	int *vals = (int *)malloc(count*sizeof(int));
	p = head;
	while (p != NULL)
	{
		vals[i] = p->val;
		i++;
		p = p->next;
	}
	//qsort(vals, count, sizeof(int), cmp);
	quickSort(vals, count);
	p = head; i = 0;
	while (p != NULL)
	{
		p->val = vals[i];
		i++;
		p = p->next;
	}
	return head;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值