各种排序算法的java实现及时间、空间复杂度、稳定程度总结

来源:互联网 发布:k means聚类算法原理 编辑:程序博客网 时间:2024/06/05 10:56

最近闲着没事,就随便看了看数据结构,看到各种排序算法时,突然心血来潮,就想,以前都是用C++实现的,能不能用java实现所有的排序算法呢?而且顺便练习一下递归的使用(因为我最不擅长使用的就是递归)

下面的代码中涉及的排序算法有

排序法

最差时间分析平均时间复杂度 稳定度 空间复杂度 选择排序O(n2)O(n2)稳定 O(1) 插入排序 O(n2)O(n2)稳定 O(1) 冒泡排序O(n2)O(n2)稳定 O(1) 快速排序O(n2)O(n*log2n)不稳定 O(log2n)~O(n)归并排序O(n^2) O(n*logn) 稳定 不一定希尔排序O(n*(logn)2)O(n*(logn)2)不稳定 O(1)堆排序O(n*log2n) O(n*log2n)不稳定 O(1) 基数排序O(kn) O (nlog(r)m)稳定 O(kn)

上面的表格有几项有必要提一下:

对于归并排序,如果不借助辅助空间的话,复杂度为O(n^2),借助的话就是O(nlogn)(O(nlog2n))归并排序 平均复杂度是 O(nlogn) 比较快。快速排序是最快的。

下面是代码实现

import java.util.ArrayList;import java.util.Iterator;public class sort {//选择排序public int[] sort1(int[] arr){for (int i = 0; i < arr.length; i++) {int temp,pos=i;int mininum=arr[i];for (int j = i; j < arr.length; j++) {if (mininum >arr[j]) {mininum=arr[j];pos=j;}}temp=arr[i];arr[i]=mininum;arr[pos]=temp;}return arr;}//冒泡排序public int[] sort2(int[] arr){for (int i = 0; i < arr.length-1; i++) {int temp;for (int j = 0; j < arr.length-1-i; j++) {if (j+1==arr.length-i) {break;}else {if(arr[j]>arr[j+1]){temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}}}return arr;}//二分插入排序(递归)public int[] sort3(int[] arr,int begin,int end){if (end==1) {return arr;}else {arr=sort3(arr, begin, end/2);for (int i = end/2; i < end; i++) {int temp;for (int j = 0; j < i; j++) {if (arr[i]<=arr[j]) {temp=arr[i];for (int k = i-1; k >j-1; k--) {arr[k+1]=arr[k];}arr[j]=temp;}else {}}}}return arr;}//二分插入排序(递归)public static ArrayList<Integer> sort3integer(ArrayList<Integer> arr,int begin,int end){if (end==1) {return arr;}else {arr=sort3integer(arr, begin, end/2);for (int i = end/2; i < end; i++) {int temp;for (int j = 0; j < i; j++) {if (arr.get(i)<=arr.get(j)) {temp=arr.get(i);for (int k = i-1; k >j-1; k--) {arr.set(k+1,arr.get(k));}arr.set(j, temp);}else {}}}}return arr;}//直接插入排序public int[] sort4(int[] arr){for (int i = 1; i < arr.length; i++) {int temp;for (int j = 0; j < i; j++) {if (arr[i]>arr[j]) {}else {temp=arr[i];for (int k = i-1; k >j-1; k--) {arr[k+1]=arr[k];}arr[j]=temp;}}}return arr;}//希尔排序(递归)public int[] sort5(int[] arr,int gap){if(gap==1){arr=sort3(arr, 0, arr.length);return arr;}else {int gap1=(gap%2==1?gap/2+1:gap/2);ArrayList<Integer>list=new ArrayList<Integer>();ArrayList<Integer>poslist=new ArrayList<Integer>();for (int i = 0; i < gap; i++) {//对每一个子序列进行插入排序int temp2=i;while(temp2<arr.length){poslist.add(temp2);list.add(arr[temp2]);temp2+=gap;}list=sort3integer(list, 0, list.size());for (int j = 0; j < list.size(); j++) {arr[poslist.get(j).intValue()]=list.get(j);}list.clear();poslist.clear();}printlist(arr);System.out.println("-->");arr=sort5(arr, gap1);}return arr;}//归并排序public ArrayList<Integer> sort6(ArrayList<Integer> arr,int begin,int end){if (begin==end-1) {return arr;}else {int mid=(begin+end)/2;ArrayList<Integer>arr1=new ArrayList<Integer>();ArrayList<Integer>arr2=new ArrayList<Integer>();for(int i=begin;i<mid;i++){arr1.add(arr.get(i));}for(int i=mid;i<end;i++){arr2.add(arr.get(i));}arr=merge(sort6(arr1, begin, mid),sort6(arr2, 0, end-mid));return arr;}}//快速排序public ArrayList<Integer> sort7(ArrayList<Integer> arr,int begin,int end){if (begin==end-1||end==begin) {return arr;}else {int temp=0,key=arr.get(begin),i=begin,j=end-1;while (i!=j) {while(arr.get(j)>=key){if (j>begin) {j--;}if (i==j) {break;}}if (i==j) {break;}temp=arr.get(i);arr.set(i, arr.get(j));arr.set(j, temp);while(arr.get(i)<key){if (i<end-1) {i++;}if (i==j) {break;}}if (i==j) {break;}temp=arr.get(i);arr.set(i, arr.get(j));arr.set(j, temp);}sort7(arr,0,i);sort7(arr,i+1,end);return arr;}}//堆排序public int[] sort8(int[] arr){if (arr.length==1) {return arr;}else {for(int i=0;i<arr.length;i++){int temp=0,leftChild=-1,rightChild=-1,end=arr.length-i;if (end>1) {//有左孩子leftChild=1;}if (end>2) {//有右孩子rightChild=2;}getMaxHeap(arr, leftChild, rightChild, end);temp=arr[0];arr[0]=arr[end-1];arr[end-1]=temp;}return arr;}}//基数排序public ArrayList<Integer> sort9(ArrayList<Integer> arr,int radix){ArrayList<ArrayList<Integer>> binarr=new ArrayList<ArrayList<Integer>>();for (int i = 0; i < 10; i++) {ArrayList<Integer>tmpArrayList=new ArrayList<Integer>();binarr.add(tmpArrayList);}int rd=1,ra=1;while(true){rd*=10;if (ra>radix) {break;}for (int i = 0; i < arr.size(); i++) {switch((arr.get(i)%rd)/(rd/10)){case 0:binarr.get(0).add(arr.get(i));break;case 1:binarr.get(1).add(arr.get(i));break;case 2:binarr.get(2).add(arr.get(i));break;case 3:binarr.get(3).add(arr.get(i));break;case 4:binarr.get(4).add(arr.get(i));break;case 5:binarr.get(5).add(arr.get(i));break;case 6:binarr.get(6).add(arr.get(i));break;case 7:binarr.get(7).add(arr.get(i));break;case 8:binarr.get(8).add(arr.get(i));break;case 9:binarr.get(9).add(arr.get(i));break;}}arr.clear();for(int i=0;i<10;i++){for (int k = 0; k < binarr.get(i).size(); k++) {arr.add(binarr.get(i).get(k));}binarr.get(i).clear();}ra++;}return arr;}//构造最大堆public static int[] getMaxHeap(int[] arr,int leftChild,int rightChild,int end){if (leftChild==-1&&rightChild==-1||rightChild==0) {//rightChild==0防止把最终父节点作为一个右孩子处理return arr;}else {int lleftChild=-1,rrightChild=-1,rleftChild=-1,lrightChild=-1;//左孩子的子节点if (leftChild*2+1<end) {lleftChild=leftChild*2+1;}if (leftChild*2+2<end){lrightChild=leftChild*2+2;}//右孩子的子节点if (rightChild*2+1<end) {rleftChild=rightChild*2+1;}if (rightChild*2+2<end){rrightChild=rightChild*2+2;}if (leftChild!=-1&&rightChild!=-1) {int parent=(leftChild-1)/2,temp=0;while(parent>=0){temp=arr[parent];if (arr[leftChild]>arr[rightChild]) {if (arr[leftChild]>arr[parent]) {arr[parent]=arr[leftChild];arr[leftChild]=temp;}}else {if (arr[rightChild]>arr[parent]) {arr[parent]=arr[rightChild];arr[rightChild]=temp;}}if(parent%2==1){//位于父节点的左孩子处leftChild=parent;rightChild=parent+1;}else {//位于父节点的右孩子处leftChild=parent-1;rightChild=parent;}parent=(leftChild-1)/2;}}else {if (leftChild!=-1&&rightChild==-1) {//只会出现只有左孩子没有右孩子的情况,不会出现相反的情况int parent=(leftChild-1)/2,temp=0;temp=arr[parent];if (arr[leftChild]>arr[parent]) {arr[parent]=arr[leftChild];arr[leftChild]=temp;}if(parent%2==1){//位于上一个的左孩子处leftChild=parent;rightChild=parent+1;}else {leftChild=parent-1;rightChild=parent;}parent=(leftChild-1)/2;while(parent>=0){temp=arr[parent];if (arr[leftChild]>arr[rightChild]) {if (arr[leftChild]>arr[parent]) {arr[parent]=arr[leftChild];arr[leftChild]=temp;}}else {if (arr[rightChild]>arr[parent]) {arr[parent]=arr[rightChild];arr[rightChild]=temp;}}if(parent%2==1){//位于父节点的左孩子处leftChild=parent;rightChild=parent+1;}else {//位于父节点的右孩子处leftChild=parent-1;rightChild=parent;}parent=(leftChild-1)/2;}}else {}}getMaxHeap(arr, lleftChild, lrightChild, end);getMaxHeap(arr, rleftChild, rrightChild, end);return arr;}}//合并两个有序子序列并返回一个有序的序列public static ArrayList<Integer> merge(ArrayList<Integer>list1,ArrayList<Integer>list2){ArrayList<Integer>newList=new ArrayList<Integer>();if (list1==null||list1.size()==0) {return list2;}if (list2==null||list2.size()==0) {return list1;}if(list1.get(list1.size()-1)<=list2.get(0)){newList.addAll(list1);newList.addAll(list2);}else {if (list2.get(list2.size()-1)<=list1.get(0)) {newList.addAll(list2);newList.addAll(list1);}else {Iterator<Integer>iterator1=list1.iterator();Iterator<Integer>iterator2=list2.iterator();boolean flag=true;Integer num1=iterator1.next();Integer num2=iterator2.next();if (num1<num2) {newList.add(num1);flag=true;}else {newList.add(num2);flag=false;}while (true) {if (flag) {if (!iterator1.hasNext()) {break;}num1=iterator1.next();}else {if (!iterator2.hasNext()) {break;}num2=iterator2.next();}if (num1<num2) {newList.add(num1);flag=true;}else {newList.add(num2);flag=false;}}if (flag) {newList.add(num2);}else {newList.add(num1);}while (iterator1.hasNext()) {newList.add(iterator1.next());}while (iterator2.hasNext()) {newList.add(iterator2.next());}}}return newList;}//打印数组public void printlist(int [] arr){System.out.println("the result:");for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+"->");}System.out.println("END");}//打印listpublic void printlist2(ArrayList<Integer> arr){System.out.println("the result:");for (int i = 0; i < arr.size(); i++) {System.out.print(arr.get(i)+"->");}System.out.println("END");}public static void main(String args[]){sort mysort=new sort();int arr[]={4,3,22,565,2,566,77,5,3,9};ArrayList<Integer>list=new ArrayList<Integer>();list.add(4);list.add(3);list.add(22);list.add(565);list.add(2);list.add(566);list.add(77);list.add(5);list.add(3);list.add(9);//mysort.printlist(mysort.sort1(arr));//mysort.printlist(mysort.sort2(arr));//mysort.printlist(mysort.sort3(arr,0,arr.length));//mysort.printlist(mysort.sort4(arr));//mysort.printlist2(mysort.sort3integer(list, 0, list.size()));//int gap1=arr.length%2==1?arr.length/2+1:arr.length/2;//mysort.printlist(mysort.sort5(arr,gap1));//mysort.printlist2(mysort.sort6(list,0,list.size()));mysort.printlist2(mysort.sort7(list,0,list.size()));//mysort.printlist(mysort.sort8(arr));//mysort.printlist2(mysort.sort9((list),3));}}


ps:上面代码包含了这几种算法的实现及测试,当然还有很多其他的算法及变种,我没涉及。还有,因为我不是很擅长计算时间复杂度和空间复杂度,所以上面表格中的归并排序和基数排序可能存在问题,还请高手不吝赐教!谢谢!!