排序算法的 java实现(一)

排序算法包括 内部排序外部排序,重点要掌握的是 八大内部排序算法:(这里假设从小到大排序)

分别是:冒泡排序、插入排序、选择排序、希尔排序、堆排序、快速排序、归并排序、基数排序


① 冒泡排序:

基本思路:在一趟排序中,从左到右扫描数组,如果发现相邻两个数中,前一个数比后一个数大,则交换两个数。第1趟排序的代码是:

for(int j = 0 ; j < arr.length - 1 - 0 ; j ++ ){
    //如果后面的数比前面的数大,则交换
    if(arr[j] > arr[j+1]){
        int temp = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = temp ; 
    }
}

因为每趟排序确定一个数在最右端,因此要对以上操作进行循环执行,冒泡排序的代码为:

public static void bubbleSort(int arr[]){
    int temp = 0 ;// 纯属用来完成交换两个数的操作
    boolean flag = false ; //用来判断该趟排序是否进行了交换,如果没有进行交换,说明数列已经有序,
                            //可以直接退出循环了,这是优化冒泡排序的重要一步
    for(int i = 0 ; i < arr.length - 1 ; i ++){ //最多进行(length-1)次排序      
        for(int j = 0 ; j < arr.length - 1 - i ; i ++) {
            if(arr[j] < a[j+1]){
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp ; 
                flag = true;
            {
        }
    if(!flag)    //若flag为false,说明一次交换也没有发生
        break;
    else    flag = false; //如果进行了交换,说明还没有排序完成,重新配置flag,进入下一轮排序
    }
    
}

② 简单选择排序:

基本思路:每一趟排序中,都选择出一个最小值,将其置于最左端,而最左端的坐标 每趟排序向右移一个单位。第1趟排序的代码为:

int minIndex = 0 ; //当前认定最小值的下标
int min = arr[0] ; 
for(int j = 0 + 1 ; j < arr.length ; j ++){
    if(min > arr[j]){
        min = arr[j];
        minIndex = j;
    }
}
//经历一趟for循环后,最小值以及坐标已经被min 和 minIndex 保存起来了
if(minIndex != 0){
    arr[minIndex] = arr[0] ; 
    arr[0] = min;
}//将最小值元素和第一个元素交换位置

简单选择排序的代码为:

// 选择排序算法
	public static void selectSort(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			int minIndex = i;//当前认定的最小值的下标
			int min = arr[i];//当前认定的最小值
			for (int j = 1 + i; j < arr.length; j++) {
				if (min > arr[j]) {//只要出现更小的数,就把值赋给min
					min = arr[j];
					minIndex = j;//赋最小值的同时,还要把最小值的位置给记录下来
				}
			}
			if (minIndex != i) {
				arr[minIndex] = arr[i];
				arr[i] = min;
				System.out.printf("第%d次排序的序列为: \n", i);
				System.out.println(Arrays.toString(arr));
			}
		}
	}

③ 直接插入排序:

该排序将数列分为有序区无序区,假设有序区在左边。每趟排序从无序区中取头一个元素放到有序区中适当的位置。寻找插入位置采用 移动法 ,即将待插入元素从 有序区最右端 开始,依次同每个元素比较,如果待插入元素 小于 当前元素,就将当前元素 向右移动一位

第一趟排序的代码如下

int insertVal = arr[1]; //此时无序区一个元素,有序区第一个元素即为数组的arr[1]
int insertIndex = 1 - 1 ;

while( insertIndex >= 0 && insertVal < arr[insertIndex] ){
    arr[insertIndex + 1 ] = arr[insertIndex ]; //将当前元素后移一位
    insertIndex -- ;//
}
if((insertIndex + 1) != 1 ){    //这个判断是减少一些不必要的插入
                                //即经过判断以后,发现元素应该插入的位置就是元素原来的位置
                                //这时候选择不插入。
    arr[insertIndex + 1] = insertVal;
}

直接插入排序的代码如下:

// 直接插入排序
	public static void insertSort(int[] arr) {
		for (int i = 1; i < arr.length; i++) {
			int insertVal = arr[i]; // 表示当前要插入到有序区去的数
			int insertIndex = i - 1;
			// 表示当前要插入的数应该在有序区的位置,是一个比较出来的值
			// 初值为有序区最右端的值
			
			/* 说明:
			 * 1、insertIndex >= 0 保证在给insertVal找插入位置不越界
			 * 2、insertVal < arr[insertIndex]表示当前还没找到插入位置,需要继续往前找
			 */
			
			while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
				arr[insertIndex + 1] = arr[insertIndex];
				insertIndex--;
			}
			if((insertIndex + 1 )!= i){
			arr[insertIndex + 1] = insertVal;
			}
			System.out.println("第"+i+"次输出的结果是:");
			System.out.println(Arrays.toString(arr));
		}
	}

④ 希尔排序:(难点)

希尔排序要求,在每趟排序中对数组按照 固定间距 进行分组,在 组内 进行插入排序。但每趟排序后需要将 固定间距 减半。   以下颜色相同的数字为一组。

 

首先确定一个增量,用int gap表示,增量的值作为“大前提”。(在平常的for循环中我们喜欢i++,这时候我们的“大前提”就是gap=1,),在大前提的基础上,逐 组 进行插入排序。(一组一组地排)

希尔排序的第1趟代码:

//假设此时gap = 5;

for(int i = 5 ; i < arr.length ; i ++){
    //以下的办法就是插入排序的办法,只是此时元素移动的单位为5
    int temp = arr[i];  //要插入的数
    int j = i - 5 ; //初始化插入的位置
    while(j >= 0 && temp < arr[j]){
        arr[j + 5] = arr[j]
        j = j - 5;
    }
    if((j + 5) != i){
        arr[j + 5] = temp ;
    }
}

希尔排序的代码:

public static void shellSortMove(int[] arr) {
		int count = 0;
		// 增量gap不变
		for (int gap = arr.length / 2; gap > 0; gap /= 2) {
			// 以gap为增量的大前提
			for (int i = gap; i < arr.length; i++) {
				// 以下的做法就是插入排序的方法:
				int temp = arr[i];// 当前要插入的数
				int j = i - gap;// 插入的位置
				while (j >= 0 && temp < arr[j]) {
					arr[j + gap] = arr[j];
					j -= gap;
				}
				if ((j + gap) != i) {
					arr[j + gap] = temp;
				}
			}

			count++;
			System.out.printf("在分组为%d的情况下,第%d 次的排序情况为:\n", gap, count);
			System.out.println(Arrays.toString(arr));
		}
	}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值