挑战算法——常见有难度的排序

本文作者在自学Android之余,决定深入研究算法,尤其是排序算法。文章以计数排序的个人经历引入,探讨了快速排序、堆排序、归并排序和基本排序方法,并分享了自己对这些算法的实现,旨在帮助读者巩固代码能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

最近课程比较松,自学Android也有一段时间了,感觉自己可以做出来一些小东西了,但是心里还是挺虚的,因为对数据结构和算法这一块一直没有深入研究。也因为学校今年才有ACM,再参加有点晚了,所以想抽出一段时间补一下算法。

正文:

那么就从排序说起吧。

不知道为什么,有时候对算法有一种敬畏感,思考起来又特别享受,有一个问题一直伴随着我,那就是自己想一个O(n)复杂度的排序算法,大二的一天中午,在北校区的操场上,突然灵感迸发,想到了一种运用数组计数的方式,那种激动的心情无法用语言描述。后来才知道这种方法叫计数排序。。。还有些小失望0.0.

好了,废话有点多。。。

那么我们常见的排序有哪些呢?

1.快速排序(JDK)

2.堆排序(TOP K问题)

3.归并排序(一些特定问题可能会用到这种思想,不一定排序)

4.插入冒泡选择

最近对这些算法做了一些自己的实现,巩固自己的代码能力,并希望对大家有所帮助。

代码:

package 所有排序的实现;
import java.util.Arrays;
public class 常见排序 {
	
	public static void main(String[] args) {
		System.out.println("sss");
		int[] list = {5,8,3,6,7,1,4,9,2,5,8,6,6,4,8,5,5,3,99,2,2,66,77,55,10,100};
		System.out.println("选择排序结果---》");
		new Xz(list);
		list = new int[]{5,8,3,6,7,1,4,9,2,5,8,6,6,4,8,5,5,3,99,2,2,66,77,55,10,100};
		System.out.println("冒泡排序结果---》");
		new Mp(list);
		list = new int[]{5,8,3,6,7,1,4,9,2,5,8,6,6,4,8,5,5,3,99,2,2,66,77,55,10,100};
		System.out.println("快速排序结果---》");
		new Qs(list);
		list = new int[]{5,8,3,6,7,1,4,9,2,5,8,6,6,4,8,5,5,3,99,2,2,66,77,55,10,100};
		System.out.println("归并排序结果---》");
		new Gb(list);
		list = new int[]{5,8,3,6,7,1,4,9,2,5,8,6,6,4,8,5,5,3,99,2,2,66,77,55,10,100};
		System.out.println("堆排序结果---》");
		new Dui(list);
	}

}
class Xz{
	public Xz(int[] list){
		sort(list);
		System.out.println(Arrays.toString(list));
	}
	public void sort(int[] list) {
		int times = 0;
		for(int i=0;i < list.length;i++){
			for(int j=i+1;j < list.length;j++){
				if(list[i] > list[j]){
					times ++;
					list[i] ^= list[j];
					list[j] ^= list[i];
					list[i] ^= list[j];
				}
			}
		}
		System.out.println("交换次数:"+times);
	}
}

class Mp{
	public Mp(int[] list){
		sort(list);
		System.out.println(Arrays.toString(list));
	}
	public void sort(int[] list) {
		int times = 0;
		for(int i=list.length-1;i>0;i--){
			for(int j=0;j<i;j++){
				if(list[j]>list[j+1]){
					times ++;
					list[j]   ^= list[j+1];
					list[j+1] ^= list[j];
					list[j]   ^= list[j+1];
				}
			}
		}
		System.out.println("交换次数:"+times);
	}
}

class Qs{
	private int times = 0;
	public Qs(int[] list){
		sort(list,0,list.length-1);
		System.out.println("交换次数:"+times);
		System.out.println(Arrays.toString(list));
	}
	public void sort(int[] list,int left,int right) {
		if(left<right){
			int mid = getMid(list, left, right);
			sort(list, left, mid);
			sort(list, mid+1, right);
		}
	}
	public int getMid(int[] list,int left,int right){//获取中间位置
		int mid = list[left];
		while(left < right){
			while(left<right && list[right]>=mid){
				right --;
			}
			list[left] = list[right];
			while(left<right && list[left]<=mid){
				left ++;
			}
			list[right] = list[left];
			times ++;
		}
		list[left] = mid;//别忘了
		return left;
	}
}

class Gb{
	private int times =0;
	
	public Gb(int[] list){
		sort(list,0,list.length-1);
		System.out.println("交换次数:"+times/2);
		System.out.println(Arrays.toString(list));
	}
	public void sort(int[] list,int left,int right){
		int mid = (left + right)/2;
		if(left<right){
			sort(list, left, mid);
			sort(list, mid+1, right);
			merge(list, left, mid, right);
		}
	}
	public void merge(int[] list,int left,int mid,int right){//合并操作
		int[] tempArr = new int[right - left +1];
		int curIndex = 0;
		int i = left;
		int j = mid + 1;
		while(i <= mid && j <= right){
			if(list[i] < list[j]){
				tempArr[curIndex++] = list[i++];
			}else{
				tempArr[curIndex++] = list[j++];
			}
			times ++;
		}
		while(i <= mid){
			tempArr[curIndex++] = list[i++];
			times++;
		}
		while (j<=right) {
			tempArr[curIndex++] = list[j++];
			times++;
		}
		for(int k=left,m=0;k<=right;){
			list[k++] = tempArr[m++];
		}
	}
}
/**
 * 堆排序:
 * 思路:
 * ⑴将一个无序序列构成一个堆
 * ⑵将堆顶元素取出,剩余元素重新构成一个堆
 */
class Dui{
	public Dui(int[] list){
//		System.out.println(Arrays.toString(list));
		buildHeap(list, 0, list.length - 1);
		System.out.println(Arrays.toString(list));
		heapSort(list, 0, list.length - 1);
		System.out.println(Arrays.toString(list));
	}
	//堆排序
	public void heapSort(int[] list,int begin,int end){
		for(int i = end;i>begin;i--){
			adjustHeap(list, begin, i);
			list[i] = list[i] + list[begin];
			list[begin] = list[i] - list[begin];
			list[i] = list[i] - list[begin];
		}
	}
	//建堆
	public void buildHeap(int[] list,int begin,int end) {
		for(int i = (begin + end)>>2+1;i>=begin;i--)
			adjustHeap(list, i, end);
	}
	//调整堆
	public void adjustHeap(int[] list,int cur,int end){
		int maxIndex = cur;
		int leftIndex = cur<<2 + 1;
		if(leftIndex<=end && list[leftIndex]>list[maxIndex]){
			maxIndex = leftIndex;
		}
		int rightIndex = cur<<2 +2;
		if(rightIndex<=end && list[rightIndex]>list[maxIndex]){
			maxIndex = rightIndex;
		}
		if(maxIndex != cur){
			list[cur] = list[cur] + list[maxIndex];
			list[maxIndex] = list[cur] - list[maxIndex];
			list[cur] = list[cur] - list[maxIndex];
			adjustHeap(list, maxIndex, end);
		}
	};
}
当然,还有一些比较sao的排序算法,像利用线程排序,巧妙运用sleep()方法,还有随机排序,当然,这些只是玩玩而已,实际应用价值并不高。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值