数据结构与算法学习Java版-排序算法介绍和分类

62 阅读3分钟

一、时间复杂度和空间复杂度介绍 

 

二、冒泡排序

冒泡排序算法代码实现 

package 数据结构;

import java.util.Arrays;
//冒泡排序
public class BubbleSort {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int [] arr=new int[] {3,9,-1,10,20};
		int temp=0;//中间变量
		boolean flag=false;//优化,在一次排序过后判断是否发生过交换
		for(int i=0;i<arr.length-1;i++) {//共进行数组大小-1次循环
			for(int j=0;j<arr.length-1-i;j++) {//每一次排序确定了一个较大的数
				if(arr[j]>arr[j+1]) {
					flag=true;
					temp=arr[j];
					arr[j]=arr[j+1];
					arr[j+1]=temp;
				}
			}
			//
			if(!flag) {
				break;//没有发生过交换说明数组已经有序
			}else {
				flag=false;//重置为false
			}
			System.out.println("第"+(i+1)+"次冒泡排序"+Arrays.toString(arr));
		}
	}

}

位运算符异或^补充 ,无需使用临时变量,但只适用整数数组的冒泡排序

package 数据结构;

import java.util.Arrays;
//冒泡排序
public class BubbleSort {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int [] arr=new int[] {3,9,-1,10,20};
		int temp=0;//中间变量
		boolean flag=false;//优化,在一次排序过后判断是否发生过交换
		for(int i=0;i<arr.length-1;i++) {//共进行数组大小-1次循环
			for(int j=0;j<arr.length-1-i;j++) {//每一次排序确定了一个较大的数
				if(arr[j]>arr[j+1]) {
					flag=true;
//					temp=arr[j];
//					arr[j]=arr[j+1];
//					arr[j+1]=temp;
					arr[j]=arr[j]^arr[j+1];
					arr[j+1]=arr[j]^arr[j+1];
					arr[j]=arr[j]^arr[j+1];
				}
			}
			//
			if(!flag) {
				break;//没有发生过交换说明数组已经有序
			}else {
				flag=false;//重置为false
			}
			System.out.println("第"+(i+1)+"次冒泡排序"+Arrays.toString(arr));
		}
	}

}

三、选择排序

package 数据结构;


import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;


public class SelectSort {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
//		int[] arr= {3,1,6,4,8};
//		selectSort(arr);
		//创建一个随机数组
		int [] arr=new int[80000];
		for(int i=0;i<80000;i++) {
			arr[i]=(int)(Math.random()*8000000);
		}
		//测试速度
		SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM--dd HH:mm:ss");
		Date date1=new Date();
		String date1Str=simpleDateFormat.format(date1);
		System.out.println("排序前时间"+date1Str);
		
		selectSort(arr);
		
		Date date2=new Date();
		String date2Str=simpleDateFormat.format(date2);
		System.out.println("排序后时间"+date2Str);
		System.out.println((date2.getTime()-date1.getTime()));
	}
	public static void selectSort(int [] arr) {
		
		
		for(int i=0;i<arr.length-1;i++) {
			int minIndex=i;
			int min=arr[i];//假定最小值
			for(int j=1+i;j<arr.length;j++) {
				if(min>arr[j]) {
					min=arr[j];//重置
					minIndex=j;
				}
			}
			if(minIndex!=i) {//假定的最小值就是最小值则不用交换
			arr[minIndex]=arr[i];
			arr[i]=min;
			}
			//System.out.println("第"+(i+1)+"次选择排序"+Arrays.toString(arr));
		}
		
	}
}

四、插入排序

package 数据结构;

import java.util.Arrays;

public class InsertSort {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int[] arr= {3,1,2,3};
		insertSort(arr);
	}
	public static void insertSort(int [] arr) {
		for(int i=1;i<arr.length;i++) {
			//定义待插入的数
			int insertVal=arr[i];//从第二个数开始
			int insertIndex=i-1;
			//确保不会数组越界insertIndex>=0
			while(insertIndex>=0&&insertVal<arr[insertIndex]) {
				arr[insertIndex+1]=arr[insertIndex];
				insertIndex--;
			}
			if(insertIndex+1!=i) {//没有此条件一样
				arr[insertIndex+1]=insertVal;
			}
		
			System.out.println("第"+i+"次插入排序"+Arrays.toString(arr));
		}
	}
}

五、希尔排序

 希尔排序交换式算法实现

package 数据结构;

import java.util.Arrays;

public class ShellSort {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int[] arr= {8,9,1,7,2,3,5,4,6,0};
		shellSort(arr);
	}
	public static void shellSort(int[] arr) {
		int temp=0;
		int count=0;
		for(int gap=arr.length/2;gap>0;gap/=2) {
			for(int i=gap;i<arr.length;i++) {//gap是步长、组数
				for(int j=i-gap;j>=0;j-=gap) {
					if(arr[j]>arr[j+gap]) {
						temp=arr[j];
						arr[j]=arr[j+gap];
						arr[j+gap]=temp;
					}
				}
			}
			System.out.println("第"+(++count)+"次希尔排序"+Arrays.toString(arr));
		}
	}
}

希尔排序移位式算法实现

package 数据结构;

import java.util.Arrays;

public class ShellSort {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int[] arr= {8,9,1,7,2,3,5,4,6,0};
		shellSort(arr);
	}
	public static void shellSort(int[] arr) {
		
		//移位式算法,速度更快
		int count=0;
		for(int gap=arr.length/2;gap>0;gap/=2) {
			//从第gap个元素开始,对其所在组进行直接插入排序
			for(int i=gap;i<arr.length;i++) {
				int j=i;
				int temp=arr[j];
				if(arr[j]<arr[j-gap]) {
					while(j-gap>=0&&temp<arr[j-gap]) {
						arr[j]=arr[j-gap];
						j-=gap;
					}
					//当退出while说明给temp找到了位置
					arr[j]=temp;
				}
			}
			System.out.println("第"+(++count)+"次希尔排序"+Arrays.toString(arr));
		}
	}
}

六、快速排序

 

 快速排序实现代码:

package 数据结构;

import java.util.Arrays;

public class QuickSort {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int[] arr= {-9,78,0,23,-56};
		quickSort(arr, 0, arr.length-1);
		System.out.println(Arrays.toString(arr));
	}
	public static void quickSort(int[] arr,int left,int right) {
		int l=left;
		int r=right;
		int mid=arr[(left+right)/2];
		int temp=0;
		while(l<r) {
			while(arr[l]<mid) {
				l+=1;
			}
			while(arr[r]>mid) {
				r-=1;
			}
			if(l>=r) {
				break;
			}
			//交换
			temp=arr[l];
			arr[l]=arr[r];
			arr[r]=temp;
			if(arr[l]==mid) {
				l++;
			}
			if(arr[r]==mid) {
				r--;
			}
		}
		if(l==r) {
			l+=1;
			r-=1;
		}
		//向左递归
		if(left<r) {
			quickSort(arr, left, r);
		}
		//向右递归
		if(right>l) {
			quickSort(arr, l, right);
		}
	}
}

七、归并排序

 

package 数据结构;

import java.util.Arrays;

public class GuiBingSort {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int[] arr= {8,4,5,7,1,3,3,2};
		int[] temp=new int[arr.length];//需要额外的空间
		guiBingSort(arr, 0, arr.length-1, temp);
		System.out.println(Arrays.toString(arr));
	}
	public static void guiBingSort(int[] arr,int left,int right,int[] temp) {
		if(left<right) {
			int mid=(left+right)/2;
			guiBingSort(arr, left, mid, temp);//向左递归分解
			guiBingSort(arr, mid+1, right, temp);//向右递归分解
			//合并
			guiBing(arr, left, mid, right, temp);
		}
		
	}
	//合并
	public static void guiBing(int[] arr,int left,int mid,int right,int[] temp) {
		int i=left;//左边有序序列的初始索引
		int j=mid+1;//右边有序序列的初始索引
		int t=0;//temp数组的当前索引
		while(i<=mid&&j<=right) {
			if(arr[i]<=arr[j]) {
				temp[t]=arr[i];
				i++;
				t++;
			}else {
				temp[t]=arr[j];
				j++;
				t++;
			}
		}
		//左边有序序列还剩余元素就依次填到temp
		while(i<=mid) {
			temp[t]=arr[i];
			i++;
			t++;
		}
		//右边有剩余
		while(j<=right) {
			temp[t]=arr[j];
			j++;
			t++;
		}
		//把temp拷贝到arr
		t=0;
		int tempLeft=left;
		while(tempLeft<=right) {
			arr[tempLeft]=temp[t];
			t++;
			tempLeft++;
		}
	}
}

八、基数排序

 

 

 

基数排序代码实现

package 数据结构;

import java.util.Arrays;

public class RadixSort {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int[] arr= {53,3,542,748,14,214};
		radixSort(arr);
	}
	public static void radixSort(int[] arr) {
		//定义一个二维数组代表10个桶
		int[][] bucket=new int[10][arr.length];
		//定义一个一维数组记录每个桶放入的数据个数
		int[] bucketElementCounts=new int[10];
		//得到数组中最大数的位数
		int max=arr[0];
		for(int i=0;i<arr.length;i++) {
			if(arr[i]>max) {
				max=arr[i];
			}
		}
		int maxLen=(max+"").length();
		//一共maxLen次排序
		for(int i=0,n=1;i<maxLen;i++,n*=10) {
			for(int j=0;j<arr.length;j++) {
				int ele=arr[j]/n%10;//依次得到各位数字
				//放到对应的桶中
				bucket[ele][bucketElementCounts[ele]]=arr[j];
				bucketElementCounts[ele]++;
			}
			//按照桶的顺序遍历每一个桶,并把数据取出放到原数组
			int ind=0;
			for(int k=0;k<bucketElementCounts.length;k++) {
				if(bucketElementCounts[k]!=0) {
					for(int l=0;l<bucketElementCounts[k];l++) {
						arr[ind]=bucket[k][l];
						ind++;
					}
				}
				//第i+1轮处理后重置为0
				bucketElementCounts[k]=0;
			}
			System.out.println("第"+(i+1)+"次基数排序"+Arrays.toString(arr));
		}
	}
}

十、排序算法的比对表