LeetCode148、215到数据结构中的排序


题目

在 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;
    }

}

5.基数排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值