前言:
最近课程比较松,自学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()方法,还有随机排序,当然,这些只是玩玩而已,实际应用价值并不高。