题目
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
输入: 4->2->1->3
输出: 1->2->3->4
输入: -1->5->3->4->0
输出: -1->0->3->4->5
排序(Sorting)是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列。
由于排序过程中涉及到的存储器不同,可以将排序方法分为两大类:内部排序和外部排序。
一、内部排序
按排序过程中依据的不同原则对内部排序方法进行分类:插入排序、交换排序、选择排序、归并排序和计数排序等。
按排序过程中所需的工作量对内部排序方法进行分类:
1.简单的排序方法,时间复杂度O(n^2)
2.先进的排序方法,时间复杂度O(nlogn)
3.基数的排序方法,时间复杂度O(d*n)
1.插入排序
2.交换排序
a>快速排序
class Solution {
public ListNode sortList(ListNode head) {
if(head==null||head.next==null) return head;
// 没有条件,创造条件。自己添加头节点,最后返回时去掉即可。
ListNode newHead=new ListNode(-1);
newHead.next=head;
return quickSort(newHead,null);
}
// 带头结点的链表快速排序
private ListNode quickSort(ListNode head,ListNode end){
if (head==end||head.next==end||head.next.next==end) return head;
// 将小于划分点的值存储在临时链表中
ListNode tmpHead=new ListNode(-1);
// partition为划分点,p为链表指针,tp为临时链表指针
ListNode partition=head.next,p=partition,tp=tmpHead;
// 将小于划分点的结点放到临时链表中
while (p.next!=end){
if (p.next.val<partition.val){
tp.next=p.next;
tp=tp.next;
p.next=p.next.next;
}else {
p=p.next;
}
}
// 合并临时链表和原链表,将原链表接到临时链表后面即可
tp.next=head.next;
// 将临时链表插回原链表,注意是插回!(不做这一步在对右半部分处理时就断链了)
head.next=tmpHead.next;
quickSort(head,partition);
quickSort(partition,end);
// 题目要求不带头节点,返回结果时去除
return head.next;
}
}
b>冒泡排序
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:
你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public int findKthLargest(int[] nums, int k) {
// 冒泡排序
int len = nums.length;
int i,j,temp;
for(i=0;i<len-1;i++){
for(j=len-1;j>i;j--){
if(nums[j]>nums[j-1]){
temp = nums[j];
nums[j]=nums[j-1];
nums[j-1]=temp;
}
}
}
return nums[k-1];
//直接调用API
// Arrays.sort(nums);
// return nums[nums.length-k];
}
}
3.选择排序
4.归并排序
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
return mergeSort(head);// 归并排序
}
private ListNode mergeSort(ListNode head){//拆分链表
// 如果没有结点或只有一个结点,无需排序,直接返回
if(head==null || head.next==null)
return head;
ListNode slow = head,fast = head.next,left,right;
while(fast!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
}
// 对右半部分进行归并排序
right = mergeSort(slow.next);
// 链表判断结束的标志:末尾节点.next==null
slow.next = null;
// 对左半部分进行归并排序
left = mergeSort(head);
return mergeList(left,right);
}
private ListNode mergeList(ListNode left,ListNode right){//合并链表
ListNode temph = new ListNode(0);
ListNode t = temph;
while(left!=null && right!=null){
if(left.val<right.val){
t.next = left;
left = left.next;
}else{
t.next = right;
right = right.next;
}
t = t.next;
}
t.next= left==null?right:left;
return temph.next;
}
}