1.冒泡排序
冒泡排序采用逐个比较的方式,可谓是最原始的排序方式。通过逐次比较 ,把最大值或最小子搬运到数组的最前端或最末端,不难分析出,冒泡排序的时间复杂度是O(n^2)。
优点:不需要额外的空间,写起来比较简单,稳定性强(然而并没有什么意义)。
缺点:时间复杂度太高了。
代码实现:
public void BubbleSort(){
for(int i=len-2;i>=0;i--){
for(int j=0;j<=i;j++){
if(arr[j].compareTo(arr[j+1])>0){
swap(j,j+1);
}
}
}
}2.快速排序
快速排序就是名气很大的快排,之所以能有这个名字是因为它的时间复杂度是O(n*logn)。但其实质上是对于冒泡排序的一种改良。快排的核心思想是从数组中找一个数,然后把数组分成两份,前一份比这个数小,后一份比这个数大,然后用相同的方法来处理前一部分和后一部分。其实不得不说快排的思想和并归排序的思想如出一辙,只能说并归排序是快排的逆过程。
优点:速度快,代码简单,不需要额外空间
缺点:不稳定(需注意的是快排时间复杂的上界等于冒泡排序的时间复杂度O(n^2)
代码实现
public void QuickSort(){
if(arr==null) return;
QuickSort(0,len-1);
}
private void QuickSort(int start,int end){
if(start>=end)return;
int index = start+1;
int index_end = end;
anytype partition = arr[start];
for(int i=start+1;i<=end;i++){
if(arr[index].compareTo(partition)<0){
swap(index,index-1);
index++;
}else{
swap(index,index_end);
index_end--;
}
}
index--;
QuickSort(start,index-1);
QuickSort(index+1,end);
}3.插入排序
插入排序的核心思想是将一个数插入已经排好序的数组速度是十分的快,插入一个数的时间复杂度是上界是n下界是1。于是你只需要把待排序的数组中的数一个一个的拿出来插到一个空的数组中(当然并不是真的是要新建一个数组),于是这个空的数组就变成一个排好序的数组。
优点:我能说是代码简介吗?不需要额外空间,稳定
缺点:速度慢(O(n^2))
代码实现:
public void insertSort(){
for(int i=1;i<len;i++){
if(arr[i].compareTo(arr[i-1])<0){
int j=i;
while(j>=1){
if(arr[j].compareTo(arr[j-1])<0){
swap(j,j-1);
j--;
}else{
break;
}
}
}
}
}4.希尔排序
希尔排序是插入排序的升级版,它的核心思想和插入排序一样,把数插到一个有序数组的速度很快,所以希尔排序的策略便是人为造成这种有序性。它通过对数组分成n个部分,进行插入排序,然后再分组,这次组数相对于上一次减少,再排序,再分组,知道组数为1。可以看出希尔排序的分组策略对算法的效率有一定的影响,一般我采用初始间隔为len/2的分法。
优点:速度快(平均速度是n^1.3),不需要额外空间
缺点:不稳定
代码实现
public void ShellSort(){
int gap = len/2;
while(gap>0){
for(int i=0;i<gap;i++){
for(int j=i+gap;j<len;j+=gap){
int z = j;
while(z-gap>=0&&arr[z].compareTo(arr[z-gap])<0){
swap(z,z-gap);
z=z-gap;
}
}
}
gap/=2;
}
}5.并归排序
并归排序之前说过了,是倒过来的快排,它的核心思想是把两个排好序的数组合并速度很快。于是它先把数组分成两份,然后对着两部分递归做相同的操作得到排好序的两个数组,然后对他们进行合并。
优点:速度快,稳定
缺点:需要额外空间,代码复杂
代码实现:
public anytype[] MergeSort(Class<anytype> type){
this.type = type;
arr = MergeSort(0,len-1);
return arr;
}
private anytype[] MergeSort(int start,int end){
if(end==start){
anytype[] tmp = getCopyArr(end-start+1);
tmp[0] = arr[start];
return tmp;
}
int mid = (end+start)/2;
anytype[] left = MergeSort(start, mid);
anytype[] right = MergeSort(mid+1, end);
anytype[] tmp = getCopyArr(end-start+1);
int leftLen = left.length;
int rightLen = right.length;
int leftId = 0;
int rightId = 0;
int id=0;
while(leftId<=leftLen-1&&rightId<=rightLen-1){
if(left[leftId].compareTo(right[rightId])<0){
tmp[id] = left[leftId];
id++;
leftId++;
}else{
tmp[id] = right[rightId];
id++;
rightId++;
}
}
if(leftId==leftLen){
for(int i=rightId;i<rightLen;i++){
tmp[id] = right[i];
id++;
}
}else{
for(int i=leftId;i<leftLen;i++){
tmp[id] = left[i];
id++;
}
}
return tmp;
}6.堆排序
要了解堆排序首先要知道堆这个数据结构,堆排序实际上就是对于堆的deleteMin操作。什么是堆?堆就是一个完全的二叉树,它保证树的根一定是最小值,并且父亲一定比儿子小。于是你只要把堆的根取出来,在恢复堆的结构,再把根取出来。。。就能得到一个有序数组。
优点:速度快且速度大体稳定(O(n*logn)),不需要额外空间
缺点:基本没有缺点,只是速度会有很小的波动,只是最坏情况和最优情况都是O(n*logn)
代码实现
public void HeapSort(){
//模拟插入 上滤
heap_insert();
//模拟删除 下滤
heap_delete();
}
private void heap_insert(){
for(int i=0;i<len;i++){
int node = i;
while(node!=0){
int father = (node+1)/2-1;
if(arr[node].compareTo(arr[father])<0){
swap(node,father);
node = father;
}else{
break;
}
}
}
}
private void heap_delete(){
for(int i=len-1;i>=0;i--){
swap(i,0);
int node = 0;
int left = (node+1)*2-1;
int right = (node+1)*2;
while(left<i){
if(right<i){
int tmp = arr[right].compareTo(arr[left])<0?right:left;
if(arr[node].compareTo(arr[tmp])>0){
swap(node,tmp);
node = tmp;
left=(node+1)*2-1;
right = (node+1)*2;
}else{
break;
}
}else{
if(arr[node].compareTo(arr[left])>0){
swap(node,left);
node = left;
left=(node+1)*2-1;
right = (node+1)*2;
}else{
break;
}
}
}
}
}
package xperdit.util;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
public class SortFactory<anytype extends Comparable<? super anytype>> {
private anytype[] arr = null;
private int len = 0;
private Class<anytype> type;
public SortFactory(anytype[] arr) {
this.arr = arr;
len = arr.length;
}
/*
* 快排 O(n*logn)
*/
public void QuickSort(){
if(arr==null) return;
QuickSort(0,len-1);
}
private void QuickSort(int start,int end){
if(start>=end)return;
int index = start+1;
int index_end = end;
anytype partition = arr[start];
for(int i=start+1;i<=end;i++){
if(arr[index].compareTo(partition)<0){
swap(index,index-1);
index++;
}else{
swap(index,index_end);
index_end--;
}
}
index--;
QuickSort(start,index-1);
QuickSort(index+1,end);
}
/*
* 冒泡排序 O(n^2)
*/
public void BubbleSort(){
for(int i=len-2;i>=0;i--){
for(int j=0;j<=i;j++){
if(arr[j].compareTo(arr[j+1])>0){
swap(j,j+1);
}
}
}
}
/*
* 堆排序 倒序 O(n)
*/
public void HeapSort(){
//模拟插入 上滤
heap_insert();
//模拟删除 下滤
heap_delete();
}
private void heap_insert(){
for(int i=0;i<len;i++){
int node = i;
while(node!=0){
int father = (node+1)/2-1;
if(arr[node].compareTo(arr[father])<0){
swap(node,father);
node = father;
}else{
break;
}
}
}
}
private void heap_delete(){
for(int i=len-1;i>=0;i--){
swap(i,0);
int node = 0;
int left = (node+1)*2-1;
int right = (node+1)*2;
while(left<i){
if(right<i){
int tmp = arr[right].compareTo(arr[left])<0?right:left;
if(arr[node].compareTo(arr[tmp])>0){
swap(node,tmp);
node = tmp;
left=(node+1)*2-1;
right = (node+1)*2;
}else{
break;
}
}else{
if(arr[node].compareTo(arr[left])>0){
swap(node,left);
node = left;
left=(node+1)*2-1;
right = (node+1)*2;
}else{
break;
}
}
}
}
}
/*
* 并归排序
*/
public anytype[] MergeSort(Class<anytype> type){
this.type = type;
arr = MergeSort(0,len-1);
return arr;
}
private anytype[] MergeSort(int start,int end){
if(end==start){
anytype[] tmp = getCopyArr(end-start+1);
tmp[0] = arr[start];
return tmp;
}
int mid = (end+start)/2;
anytype[] left = MergeSort(start, mid);
anytype[] right = MergeSort(mid+1, end);
anytype[] tmp = getCopyArr(end-start+1);
int leftLen = left.length;
int rightLen = right.length;
int leftId = 0;
int rightId = 0;
int id=0;
while(leftId<=leftLen-1&&rightId<=rightLen-1){
if(left[leftId].compareTo(right[rightId])<0){
tmp[id] = left[leftId];
id++;
leftId++;
}else{
tmp[id] = right[rightId];
id++;
rightId++;
}
}
if(leftId==leftLen){
for(int i=rightId;i<rightLen;i++){
tmp[id] = right[i];
id++;
}
}else{
for(int i=leftId;i<leftLen;i++){
tmp[id] = left[i];
id++;
}
}
return tmp;
}
/*
* 插入排序
*/
public void insertSort(){
for(int i=1;i<len;i++){
if(arr[i].compareTo(arr[i-1])<0){
int j=i;
while(j>=1){
if(arr[j].compareTo(arr[j-1])<0){
swap(j,j-1);
j--;
}else{
break;
}
}
}
}
}
/*
* 希尔排序
*/
public void ShellSort(){
int gap = len/2;
while(gap>0){
for(int i=0;i<gap;i++){
for(int j=i+gap;j<len;j+=gap){
int z = j;
while(z-gap>=0&&arr[z].compareTo(arr[z-gap])<0){
swap(z,z-gap);
z=z-gap;
}
}
}
gap/=2;
}
}
private anytype[] getCopyArr(int length){
anytype[] tmp = (anytype[]) Array.newInstance(type, length);
return tmp;
}
private void swap(int i,int j){
anytype tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}

545

被折叠的 条评论
为什么被折叠?



