Java实现冒泡、插入、选择、基数排序

1 冒泡排序

       冒泡排序的算法比较简单,每一轮遍历数列,将数列中最大(或最小)的元素放到数列的头部(或尾部),这个最大(或最小)元素就是本轮的冒泡元素,冒泡元素的位置应该在数列的"头部+n"(或"尾部-n")的位置,n表示遍历的轮次。在下图的描述中,我们将数列中元素最大的元素在尾部"冒泡"。

冒泡排序

冒泡排序过程

       在下面的程序实现中,我们将数组中每轮找到的最大元素"冒泡"在数组的尾部。具体算法实现如下面示例所示。

示例 冒泡排序
	public class BubbleSort {
		
		//打印数组
		public static void printArray(int[] array) {
			int length=array.length;
			for(int i=0;i<length;i++) {
				System.out.print(array[i]);
				System.out.print(i!=length-1?",":"\n");
			}
		}
		//冒泡排序
		public static void sort(int[] array) {
			
			for(int i=0;i<array.length;i++) {//外层循环,记录排序的轮次
				/** 内存循环用于俩俩比较,从数组第一个元素比较到数组长度减i个轮次.
				 * 第一轮从1到length-0,第二轮从1到length-1,依次类推*/
				for(int j=1;j<array.length-i;j++) {
					//当前一元素大于后一个元素,交换二者的位置。实现大元素后移
					if(array[j-1]>array[j]) {
						int temp=array[j-1];
						array[j-1]=array[j];
						array[j]=temp;
					}
				}
				System.out.print("第"+(i+1)+"轮结束后,数组的内容为:");
				printArray(array);
			}
		}
	
		public static void main(String[] args) {
	
			int[] array= {1,4,3,-100,323,53,13,554,123,20,43,12};
			sort(array);
	
		}
	}

示例运行结果:

       第1轮结束后,数组的内容为:1,3,-100,4,53,13,323,123,20,43,12,554
       第2轮结束后,数组的内容为:1,-100,3,4,13,53,123,20,43,12,323,554
       第3轮结束后,数组的内容为:-100,1,3,4,13,53,20,43,12,123,323,554
       第4轮结束后,数组的内容为:-100,1,3,4,13,20,43,12,53,123,323,554
       第5轮结束后,数组的内容为:-100,1,3,4,13,20,12,43,53,123,323,554
       第6轮结束后,数组的内容为:-100,1,3,4,13,12,20,43,53,123,323,554
       第7轮结束后,数组的内容为:-100,1,3,4,12,13,20,43,53,123,323,554
       第8轮结束后,数组的内容为:-100,1,3,4,12,13,20,43,53,123,323,554
       第9轮结束后,数组的内容为:-100,1,3,4,12,13,20,43,53,123,323,554
       第10轮结束后,数组的内容为:-100,1,3,4,12,13,20,43,53,123,323,554
       第11轮结束后,数组的内容为:-100,1,3,4,12,13,20,43,53,123,323,554
       第12轮结束后,数组的内容为:-100,1,3,4,12,13,20,43,53,123,323,554

2 插入排序

       插入算法比较直观,它的思想是从前端构建有序数列,后端未排序的元素和向前端有序数列中的元素从后向前依次比较,如果比前面元素大,该元素位置不变,继续排序下一个未排序元素。如果比前面元素小,将该元素插入到比较元素之前,然后继续比较有序数列前一个元素,直到当前元素插入到有序数列合适位置。插入算法图解如下图所示。

插入排序

插入排序过程

       采用插入算法排序时,我们的程序会将数组分为两段,前一段是经过排序的有序数列,我们记为a0、a1、a2……ai。未排序部分为ai+1、ai+2……。在排序的时,用ai+1和ai比较,如果ai+1大于ai,ai+1排序完成,进行ai+2的排序。如果小于ai,将ai+1插入到ai的前面,在去比较ai-1,直到ai+1找好合适位置。具体算法实现如下面示例所示。

示例 插入排序算法
	public class InsertionSort {
		
		    //打印数组
			public static void printArray(int[] array) {
				int length=array.length;
				for(int i=0;i<length;i++) {
					System.out.print(array[i]);
					System.out.print(i!=length-1?",":"\n");
				}
			}
			//冒泡排序
			public static void sort(int[] array) {
				//未排序数列起始位置开始排序,i为未排序数列的起点索引
				for(int i = 1;i<array.length;i++) {
			   /**
				* 第一个未排序元素array[j]与有序数列最后一个元素<array[j-1]比较,
				* 如果array[j]大,排序完成,外层循环继续。
				* 如果array[j]小,交换array[j]和array[j-1]位置,在比较前一个有序元素。
			   */
		         	for(int j=i;j>0 && array[j]<array[j-1];j--) {
		              	int temp=array[j];
		              	array[j]=array[j-1];
		              	array[j-1]=temp;
		            }
		         	System.out.print("第 "+i+"轮插入排序后的结果:");
		         	printArray(array);
				}
			}
			
			public static void main(String[] args) {
				int[] array= {99,4,3,-100,323,53,13,554,123,20,43,12};
				sort(array);
			}
	}

示例运行结果:
       第 1轮插入排序后的结果:4,99,3,-100,323,53,13,554,123,20,43,12
       第 2轮插入排序后的结果:3,4,99,-100,323,53,13,554,123,20,43,12
       第 3轮插入排序后的结果:-100,3,4,99,323,53,13,554,123,20,43,12
       第 4轮插入排序后的结果:-100,3,4,99,323,53,13,554,123,20,43,12
       第 5轮插入排序后的结果:-100,3,4,53,99,323,13,554,123,20,43,12
       第 6轮插入排序后的结果:-100,3,4,13,53,99,323,554,123,20,43,12
       第 7轮插入排序后的结果:-100,3,4,13,53,99,323,554,123,20,43,12
       第 8轮插入排序后的结果:-100,3,4,13,53,99,123,323,554,20,43,12
       第 9轮插入排序后的结果:-100,3,4,13,20,53,99,123,323,554,43,12
       第 10轮插入排序后的结果:-100,3,4,13,20,43,53,99,123,323,554,12
       第 11轮插入排序后的结果:-100,3,4,12,13,20,43,53,99,123,323,554

3 选择排序

       选择排序需要定义额外的变量来保存元素信息。采用选择排序,我们需要定义一个变量minIndex用于保存数组中最小元素的索引。在第一轮遍历过程中,minIndex始终存储数组中数值最小元素的索引,在第一轮遍历结束后,将数组中第一个元素与minIndex位置的元素交换位置,第二轮遍历过程中,minIndex始终存储数组数值第二小的元素索引,遍历结束后将minIndex索引处的元素放置数组第二的位置上,以此类推完成所有排序。选择排序图解如下图所示。

选择排序

选择排序

       使用选择排序需要使用额外的存储空间,在实现选择排序时,我们要保证每一轮将数组中元素的最小元素放置到数组的头部,依次进行排序。具体算法实现如下面示例所示。

示例 选择排序
	public class SelectionSort {
	
	    //打印数组
		public static void printArray(int[] array) {
			int length=array.length;
			for(int i=0;i<length;i++) {
				System.out.print(array[i]);
				System.out.print(i!=length-1?",":"\n");
			}
		}
		
		public static void sort(int[] array) {
			//排序的轮次,i记录未排序数列的起始索引位置
			for(int i=0;i<array.length;i++) {
				//minIndex记录未排序元素的最小值的索引,默认未排序数列第一元素为最小
				int minIndex=i;
				//从未排序数列第二个元素开始于当前最小元素做遍历比较
				for(int j=i+1;j<array.length;j++) {
	            	//如果有元素比当前最小元素小,修改minIndex保存的索引值
	              	if(array[j]<array[minIndex]) {
	              		minIndex=j;
	              	}
				}
				//将每一轮最小元素放置到未排序数列的首位
				int temp=array[minIndex];
				array[minIndex]=array[i];
				array[i]=temp;    
				System.out.print("第"+(i+1)+"次排序后的结果:");
				printArray(array);
		     }
	
		}
		
		public static void main(String[] args) {
			int[] array= {99,4,3,-100,323,53,13,554,123,20,43,12};
			sort(array);
		}
	}

示例运行结果:
       第1次排序后的结果:-100,4,3,99,323,53,13,554,123,20,43,12
       第2次排序后的结果:-100,3,4,99,323,53,13,554,123,20,43,12
       第3次排序后的结果:-100,3,4,99,323,53,13,554,123,20,43,12
       第4次排序后的结果:-100,3,4,12,323,53,13,554,123,20,43,99
       第5次排序后的结果:-100,3,4,12,13,53,323,554,123,20,43,99
       第6次排序后的结果:-100,3,4,12,13,20,323,554,123,53,43,99
       第7次排序后的结果:-100,3,4,12,13,20,43,554,123,53,323,99
       第8次排序后的结果:-100,3,4,12,13,20,43,53,123,554,323,99
       第9次排序后的结果:-100,3,4,12,13,20,43,53,99,554,323,123
       第10次排序后的结果:-100,3,4,12,13,20,43,53,99,123,323,554
       第11次排序后的结果:-100,3,4,12,13,20,43,53,99,123,323,554
       第12次排序后的结果:-100,3,4,12,13,20,43,53,99,123,323,554

4 基数排序

       前面几种排序算法总体上来说都是比较排序,即在排序的过程中需要进行比较,而基数排序是不需要比较的。基数排序是先从元素的低位开始排序,相同数值的收集在一起,然后再往高位依次进行排序收集,直至最高位被排序完毕,收集后的元素序列就是一个有序数列。下面一系列图片中描述了基数排序的过程。

在这里插入图片描述

第一次,个位排序

       当个位排序完成后,收集的时候从0到9数值位依次收集数据,收集后的数列供十位排序使用。

在这里插入图片描述

第二次,十位排序

       在十位排序的时候,部分元素在十位上没有数值,这些元素的十位数值都按0处理。

在这里插入图片描述

最后一次,百位排序

       由于数列中最大的数只有三位,所以当百位排序完成后,基数排序完成。收集后的数列就是一个从小到大的有序数列。代码实现如下所示:

	import java.util.ArrayList;
	import java.util.HashMap;
	import java.util.Iterator;
	import java.util.List;
	import java.util.Map;
	
	public class RadixSort {
			//打印数组
			public static void printArray(int[] array) {
				int length=array.length;
				for(int i=0;i<length;i++) {
					System.out.print(array[i]);
					System.out.print(i!=length-1?",":"\n");
				}
			}
			//按基数排序,注意这里只能排序正整数。
			public static void sort(int[] array) {
				//找到数组中最大数max,并计算它的位数maxDig
				int max=array[0];
				for(int maxTemp:array) {
					if(maxTemp>max) max=maxTemp;
				}
				int maxDig=String.valueOf(max).length();
				//创建从0~9的基数数据集
				Map<Integer,List<Integer>> map=new HashMap<>();
				for(int i=0;i<10;i++) {
					map.put(i, new ArrayList<Integer>());
				}
				//从低位baseDig开始到高位maxDig进行指定位的基数排序
				int baseDig=1;
				while(baseDig<=maxDig) {
					System.out.println("####开始从低位的第"+baseDig
									+"位开始基数排序####");
					//第一阶段,遍历目标数组,将数组元素放入指定的基数数集中
					for(int temp:array) {
	
						String strVal=String.valueOf(temp);
						//获取元素baseDig位的数字,放入相对的基数数据集中。
						//如果不存在,将该元素放入0基数数据集中。
						Integer key=null;
						if(strVal.length()<baseDig) {
							key=0;
						}else {
							//获取指定位上的字符,并转化成目标基数key。
							char bitNum=strVal.charAt(strVal.length()-baseDig);
							key=Integer.valueOf(String.valueOf(bitNum));
						}
						map.get(key).add(temp);
					}
				
					int j=0;
					System.out.println("从低位起,第"+baseDig
									+"位基数排序后,各基数数据集的结果:");
					//第二阶段,将0~9基数数据集中的数据,放回到数组中,
					//表示当前baseDig位的基数排序完成
					for(int i=0;i<10;i++) {
						if(map.get(i).size()>=1) {
							System.out.println(i+":"+map.get(i));
						}
						Iterator<Integer> it=map.get(i).iterator();
						
						while(it.hasNext()) {
							array[j++]=it.next();
						}
						map.get(i).clear();
					}
					System.out.print("第"+baseDig
									+"位基数排序完成后,目标数组的结果:");
					printArray(array);
					baseDig++;
				}
			}
	
			public static void main(String[] args) {
				//要排序的目标数组
				int[] array= {1,4,3,100,323,53,13,559230,123,20,43,12};
				sort(array);
			}
	}

示例运行结果:
       ####开始从低位的第1位开始基数排序#####
       从低位起,第1位基数排序后,各基数数据集的结果:
       0:[100, 559230, 20]
       1:[1]
       2:[12]
       3:[3, 323, 53, 13, 123, 43]
       4:[4]
       第1位基数排序完成后,目标数组的结果:100,559230,20,1,12,3,323,53,13,123,43,4
       ####开始从低位的第2位开始基数排序#####
       从低位起,第2位基数排序后,各基数数据集的结果:
       0:[100, 1, 3, 4]
       1:[12, 13]
       2:[20, 323, 123]
       3:[559230]
       4:[43]
       5:[53]
       第2位基数排序完成后,目标数组的结果:100,1,3,4,12,13,20,323,123,559230,43,53
       ####开始从低位的第3位开始基数排序#####
       从低位起,第3位基数排序后,各基数数据集的结果:
       0:[1, 3, 4, 12, 13, 20, 43, 53]
       1:[100, 123]
       2:[559230]
       3:[323]
       第3位基数排序完成后,目标数组的结果:1,3,4,12,13,20,43,53,100,123,559230,323
       ####开始从低位的第4位开始基数排序#####
       从低位起,第4位基数排序后,各基数数据集的结果:
       0:[1, 3, 4, 12, 13, 20, 43, 53, 100, 123, 323]
       9:[559230]
       第4位基数排序完成后,目标数组的结果:1,3,4,12,13,20,43,53,100,123,323,559230
       ####开始从低位的第5位开始基数排序#####
       从低位起,第5位基数排序后,各基数数据集的结果:
       0:[1, 3, 4, 12, 13, 20, 43, 53, 100, 123, 323]
       5:[559230]
       第5位基数排序完成后,目标数组的结果:1,3,4,12,13,20,43,53,100,123,323,559230
       ####开始从低位的第6位开始基数排序#####
       从低位起,第6位基数排序后,各基数数据集的结果:
       0:[1, 3, 4, 12, 13, 20, 43, 53, 100, 123, 323]
       5:[559230]
       第6位基数排序完成后,目标数组的结果:1,3,4,12,13,20,43,53,100,123,323,559230

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值