面试必备——八大排序(JAVA)

直接插入排序

public void sort(int[] nums){
	for(int i = 1; i < nums.length;i++){
		int tmp = nums[i];
		int j;
		for(j = i; j>=0 && tmp < nums[j-1];j--){
				nums[j] = nums[j-1];
		}
		num[j] = tmp;
	}
}
平均时间复杂度最好情况最坏情况空间复杂度稳定性
O(n²)O(n²)O(n²)O(1)稳定

希尔排序

希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。已知的最好步长序列是由Sedgewick提出的(1, 5, 19, 41, 109,…)。

这项研究也表明“比较在希尔排序中是最主要的操作,而不是交换。”用这样步长序列的希尔排序比插入排序和堆排序都要快,甚至在小数组中比快速排序还快,但是在涉及大量数据时希尔排序还是比快速排序慢。

public void sort(int[] a)
{
	int h = 1;
	int len = a.length;
	while( h < len / 3) h = h * 3 + 1;
	for(;h>=1;h/=3)
	{
		for(int i = 0; i < len-h; i+=h)
		{
			for(int j = i+h; j > 0; j-=h)
			{
				if( a[j] < a[j-h])
				{
					int tmp = a[j];
					a[j] = a[j-h];
					a[j-h] = tmp;
				}
			}
		}
	}
}
平均时间复杂度最好情况最坏情况空间复杂度稳定性
O(nlog2 n)O(nlog2 n)O(nlog2 n)O(1)不稳定

选择排序

public void sort(int[] a)
{
	for(int i = 0; i < a.length; i++)
	{
		int min = i;
		for(int j = i+1; j < a.length; j++)
		{
			if(a[min]>a[j])
			{
				min = j;
			}
		}
		if(min!=i)
		{
			int tmp = a[min];
			a[min] = a[i];
			a[i] = tmp;
		}
	}
}
平均时间复杂度最好情况最坏情况空间复杂度稳定性
O(n²)O(n²)O(n²)O(1)不稳定

堆排序

//小根堆
public void heapsort(int[] a,int n){
   for(int i = (n-2)/2;i>=0;i--){
        maxheap(a,i,n);
    }
    int end = n-1;
    while(end > 0){
        swap(a,0,end);
        maxheap(a, 0, end);
        end--;
    }
}
void maxheap(int[] a, int root, int len){
    int parent = root;
    int child = parent * 2 + 1;
    while(child < len){
        if((child+1)<len&&a[child+1]<a[child]){
            child++;
        }
        if(a[child]<a[parent]){
            swap(a,child,parent);
            parent = child;
            child = parent *2 +1;
        }
        else break;
    }
}
void swap(int[] a, int i ,int j){
    int tmp = a[i];
    a[i] = a[j];
    a[j]= tmp;
}

//大根堆
public void heapsort(int[] a,int n){
        for(int i = (n-2)/2;i>=0;i--){
            maxheap(a,i,n);
        }
        int end = n-1;
        while(end > 0){
            swap(a,0,end);
            maxheap(a, 0, end);
            end--;
        }
    }
    void maxheap(int[] a, int root, int len){
        int parent = root;
        int child = parent * 2 + 1;
        while(child < len){
            if((child+1)<len&&a[child+1]>a[child]){
                child++;
            }
            if(a[child]>a[parent]){
                swap(a,child,parent);
                parent = child;
                child = parent *2 +1;
            }
            else break;
        }
    }
    void swap(int[] a, int i ,int j){
        int tmp = a[i];
        a[i] = a[j];
        a[j]= tmp;
    }
平均时间复杂度最好情况最坏情况空间复杂度稳定性
𝑂(𝑛log2𝑛)𝑂(𝑛log2𝑛)𝑂(𝑛log2𝑛)O(1)不稳定

冒泡排序

public static void sort(int[] a)
{
	for(int i = 0; i < a.length - 1; i++)
	{
		for(int j = 0; j < a.length - 1 - i; j++)
		{
			if(a[j] > a[j+1])
			{
				int tmp = a[j];
				a[j] = a[j+1];
				a[j+1] = tmp;
			}
		}
	}
}
平均时间复杂度最好情况最坏情况空间复杂度稳定性
O(n²)O(n)O(n²)O(1)稳定

快速排序

public static void sort(int[] a,int low,int high)
{
	if(low >= high)
	{
		return;
	}
	int left = low;
	int right = high;
	int pivot = a[low];
	while(left < right)
	{
		//这两个while的顺序一定不能改,必须要先从右往左减,然后再从左往右,因为一开始取的key在左端
		//具体原因见https://blog.csdn.net/he37176427/article/details/97795963
		while(left < right && a[right] >= pivot)
			right--;
		while(left < right && a[left] <= pivot)
			left++;
		if(left<right){
			int tmp = a[left];
			a[left] = a[right];
			a[right] = tmp;
		}
	}
	a[low] = a[left];
	a[left] = pivot;
	sort(a,low,left-1);
	sort(a,left+1,high);
}
平均时间复杂度最好情况最坏情况空间复杂度稳定性
O(nlogn)O(nlogn)O(n²)O(nlogn)不稳定

快排改进(三向快速排序)

public static void sort(int[] a,int lo,int hi)
{
	if(lo >= hi)
	{
		return;
	}
	int v = a[lo], lt = lo, i = lo + 1, gt = hi;
	while(i <= gt)
	{
		if(a[i] < v)
		{
			swap(a,i++,lt++)
		}
		else if(a[i] > v)
		{
			swap(a,i,gt--);
		}else 
		{
			i++;
		}
	}
	sort(a, lo, lt - 1);
	sort(a, gt + 1, hi);
}
private static void swap(int[] a, int i, int j)
{
	int t = a[i];
	a[i] = a[j];
	a[j] = t;
}
平均时间复杂度最好情况最坏情况空间复杂度稳定性
O(nlogn)O(nlogn)O(n²)O(1)不稳定

归并排序

public static sort(int[] a,int low,int high){
	int mid = (low + high) / 2;
	if(low < high){
		sort(a, low, mid);
		sort(a, mid + 1, high);
		merge(a, low, mid, high);
	}
	return a;
}
public static void merge(int[] a, int low, int mid, int high)
{
	int[] tmp = new int[high - low + 1];
	int i = low;
	int j = mid + 1;
	int k = 0;
	
	while(i <= mid && j <= high){
		if(a[i] < a[j]){
			tmp[k++] = a[i++];
		}else{
			tmp[k++] = a[j++];
		}
	}
	while(i <= mid){
		tmp[k++] = a[i++];
	}
	while(j <= high){
		tmp[k++] = a[j++];
	}

	for(int x = 0;x < tmp.length; x++)
	{
		a[x+low] = tmp[x];
	}
}
平均时间复杂度最好情况最坏情况空间复杂度稳定性
𝑂(𝑛log2𝑛)𝑂(𝑛log2𝑛)𝑂(𝑛log2𝑛)O(n)稳定

基数排序

private static void sort(int[] a)
{
//找出最大的数字,并且取得最大数字的位数
	int max = 0;
	for(int i = 0; i < a.length; i++)
	{
		if(max < a[i])
			max = a[i];
	}
	int maxDigit = 1;
	while(max / 10 > 0){
		maxDigit++;
		max /= 10;
	}
	
	int[][] buckets = new int[10][a.length];
	int base = 10;

	for(int i = 0; i < maxDigit; i++)
	{
		int[] bktLen = new int[10];

		for(int j = 0; j < a.length; j++)
		{
			int whichBucket = (a[j]%base)/(base/10);
			buckets[whichBucket][bktLen[whichBucket]] = arr[j];
			bktLen[whichBucket]++;
		}
		int k = 0;
		for(int b = 0; b < buckets.length; b++){
			for(int p = 0; p < bktLen[b]; p++){
				a[k++] = buckets[b][p];
			}
		}
		base *= 10;
	}
}
平均时间复杂度最好情况最坏情况空间复杂度稳定性
O(d*(n+r))O(d*(n+r))O(d*(n+r))O(n+r)稳定
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值