基础算法-排序

本文详细介绍了几种常见的排序算法,包括冒泡排序、快速排序、选择排序、归并排序,并提供了相应的Java实现。此外,还讲解了如何计算数列的逆序对数量以及利用堆排找出数列中前m小的数的方法。这些内容涵盖了基础算法和数据结构的应用,对于理解排序和数据处理有很好的指导作用。

排序

冒泡排序

    public static void    bublle_sort(int q[],int n){
        for(int i=0;i<n-1;i++)
            for(int j=0;j<n-1-i;j++)
                if(q[j]>q[j+1]){
                    int t=q[j];
                    q[j]=q[j+1];
                    q[j+1]=t;
                }
    }

快速排序

import java.util.*;
public class Main{
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int q[]=new int[n];
        for(int i=0;i<n;i++)q[i]=sc.nextInt();
        q_sort(q,0,n-1);
        for(int i=0;i<n;i++)System.out.print(q[i]+" ");
    }
    public static void q_sort(int q[],int l,int r){
        if(l>=r)return;
        int i=l-1,j=r+1,mid=q[l+r >>1];
        while(i<j){
            while(q[++i]<mid);
            while(q[--j]>mid);
            if(i<j){
                int temp=q[i];
                q[i]=q[j];
                q[j]=temp;
            }
        }
        q_sort(q,l,j);
        q_sort(q,j+1,r);
        }
    }
}

第k小的数

在这里插入图片描述

import java.util.*;
public class select_sort{
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int k=sc.nextInt();
        int q[]=new int[n];
        for(int i=0;i<q.length;i++)q[i]=sc.nextInt();
        int res=select_sort(q,0,n-1,k);
        System.out.print(q[res]);
    }
    public static int select_sort(int q[],int l,int r,int k){
        if(l>=r)return l;
        int i=l-1,j=r+1,mid=q[l + r >>1];
        while(i<j){
            while(q[++i]<mid);
            while(q[--j]>mid);
            if(i<j){
                int temp=q[i];
                q[i]=q[j];
                q[j]=temp;
            }
        }
        int dis=j-l+1;
        if(k<=dis)return select_sort(q,l,j,k);
        else return select_sort(q,j+1,r,k-dis);    //k在后半部分的相对位置
    }
}

归并排序

归并排序模板

    public static void merge_sort(int arr[],int l,int r){
        if(l==r)return;    //递归结束条件
        int mid=(l+r)>>1;    //选取分界点
        int i=l,j=mid+1,k=0;    //分界后的两个起点
        int temp[]=new int[r-l+1];
        merge_sort(arr,l,mid);
        merge_sort(arr,mid+1,r);
        while(i<=mid&&j<=r){
            if(arr[i]<=arr[j])temp[k++]=arr[i++];
            else temp[k++]=arr[j++];
        }
        while(i<=mid)temp[k++]=arr[i++];    //处理后续
        while(j<=r)temp[k++]=arr[j++];
        for(i=l,j=0;i<=r;i++,j++)arr[i]=temp[j];    //交回
    }

数列逆序对数量

在这里插入图片描述

import java.util.*;
import java.io.*;
public class Main{
    public static void main(String[] args) {
        Scanner sc=new Scanner(new InputStreamReader(System.in));
        int n=sc.nextInt();
        int []a=new int[n];
        for(int i=0;i<n;i++)
            a[i]=sc.nextInt();

        System.out.println(merge_sort(a,0,n-1));
        sc.close();
    }
    public static long merge_sort(int []a,int l,int r){
        if(l==r)return 0;    //逆序对数量为0时结束递归
        int []t=new int [r-l+1];
        int mid=l + r >>1;
        long  res=merge_sort(a,l,mid)+merge_sort(a,mid+1,r);
        int k=0,i=l,j=mid+1;
    
        while(i<=mid&&j<=r){
            if(a[i]<=a[j]){
                t[k++]=a[i++];
            }else{
                res+=mid-i+1;    //此时左边部分i之后的都大于右边的这个数,形成逆序对
                t[k++]=a[j++];
            }
        }
        while(i<=mid)t[k++]=a[i++];
        while(j<=r)t[k++]=a[j++];
        for(i=l,j=0;i<=r;i++,j++)a[i]=t[j];
        return res;
    }
}

堆排-前m小的数

在这里插入图片描述
每次形成小根堆,输出堆顶最小值,再用堆尾将其覆盖(相当于删除当前数组的首元素),重新形成小根堆,此时堆顶就是次小元素,将其输出,每一次形成堆都会是剩余的最小值

import java.util.Scanner;
public class Main{
	static  int N=100010;
	static int []h=new int[N];
	static int size;//堆的右边界
	
	public static void down(int u){
		int t=u;//t保存最小结点的下标
		//左儿子存在且左儿子小于父节点,替换坐标
		if(2*u<=size&&h[2*u]<h[t])t=2*u;
		
		//右儿子存在且右儿子小于父节点,替换坐标
		if(2*u+1<=size&&h[2*u+1]<h[t])t=2*u+1;
		if(u!=t){	//最小结点不是t,则与最小值交换
			swap(u,t);
			down(t);	//递归最小值t
		}
	}
	public static  void swap(int x,int y){
		int temp=h[x];
		    h[x]=h[y];
		    h[y]=temp;
	}
    public static void main(String[] args) {
    	Scanner sc=new Scanner(System.in);
    	int n=sc.nextInt();
    	size=n;	//右边界
    	int m=sc.nextInt();
    	for(int i=1;i<=n;i++)h[i]=sc.nextInt();	//下标从1开始
    	for(int i=n/2;i>=1;i--)down(i);	//形成小根堆
    	while(m-->0){	//先后输出m个最小值
    		System.out.print(h[1]+" ");	//输出堆顶最小值
    		h[1]=h[size--];	//相当于覆盖并删除掉最小值
    		down(1);
    	}
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值