`

基本排序算法回顾-bubble/select/insert

 
阅读更多

没有独立的文字说明,因为是边回忆,边写,边查经典,所以所有的文字说明都在代码中。呵呵

 

package org.acooly.datastructure.sort;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.math.RandomUtils;

/**
 * 排序算法回顾和学习 <br>
 * <li>先回忆下算法,然后根据普通逻辑思维,写my排序算法()。 
 * <li>翻开经典《JAVA数据结构和算法第二部》,学习经典排序算法,然后对比学习
 * 
 * @author zhangpu
 * 
 */
public abstract class JavaBaseSort {

	// { 3, 21, 46, 75, 56, 39, 7, 95, 93, 1 };
	public static void main(String[] args) {
		int dataSize = 10;
		int[] randomData = new int[dataSize];
		for (int i = 0; i < randomData.length; i++) {
			int member = RandomUtils.nextInt(dataSize * 10);
			if (!ArrayUtils.contains(randomData, member)) {
				randomData[i] = member;
			} else {
				i--;
			}
		}

		long start = 0;
		int[] data = randomData.clone();
		System.out.println("我的冒泡排序:");
		printArray("原始数据: ", data = new int[]{6,5,4,67,23,3,12,32,30,1});
		start = System.currentTimeMillis();
		myBubbleSort(data);
		System.out.println("排序时间: " + (System.currentTimeMillis() - start) + "ms");
		printArray("排序数据:", data);

		System.out.println();

		System.out.println("经典冒泡排序:");
		printArray("原始数据: ", data = randomData.clone());
		start = System.currentTimeMillis();
		bubbleSort(data);
		System.out.println("排序时间: " + (System.currentTimeMillis() - start) + "ms");
		printArray("排序数据: ", data);

		System.out.println();
		System.out.println();

		System.out.println("我的选择排序:");
		printArray("原始数据: ", data = randomData.clone());
		start = System.currentTimeMillis();
		mySelectSort(data);
		System.out.println("排序时间: " + (System.currentTimeMillis() - start) + "ms");
		printArray("排序数据: ", data);

		System.out.println();

		System.out.println("经典选择排序:");
		printArray("原始数据: ", data = randomData.clone());
		start = System.currentTimeMillis();
		selectSort(data);
		System.out.println("排序时间: " + (System.currentTimeMillis() - start) + "ms");
		printArray("排序数据: ", data);

		System.out.println();
		System.out.println();

		System.out.println("我的插入排序:");
		printArray("原始数据: ", data = randomData.clone());
		start = System.currentTimeMillis();
		myInsertSort(data);
		System.out.println("排序时间: " + (System.currentTimeMillis() - start) + "ms");
		printArray("排序数据: ", data);

		System.out.println();

		System.out.println("经典插入排序:");
		printArray("原始数据: ", data = randomData.clone());
		start = System.currentTimeMillis();
		insertSort(data);
		System.out.println("排序时间: " + (System.currentTimeMillis() - start) + "ms");
		printArray("排序数据: ", data);
	}

	/**
	 * 我的写法
	 * 逐个与开始位置的比较,小的向左边沉
	 * @param data
	 */
	public static void myBubbleSort(int[] data) {
		int swapCount = 0;
		int loopCount = 0;
		for (int j = 0; j < data.length - 1; j++) {
			for (int i = j+1; i < data.length; i++) {
				if (data[j] > data[i]) {
					swap(data, j, i);
					swapCount++;
				}
				loopCount++;
			}
		}
		System.out.println("交换次数:" + swapCount);
		System.out.println("比较次数:" + loopCount);
	}

	/**
	 * JAVA数据结构和算法第二版的写法 <br>
	 * 书中算法有小BUG,原书中out > 1,应该是大于0,或in < out修改为in <= out
	 * 
	 * @param data
	 */
	public static void bubbleSort(int[] data) {
		int swapCount = 0;
		int loopCount = 0;
		for (int out = data.length - 1; out > 0; out--) {
			for (int in = 0; in < out; in++) {
				if (data[in] > data[in + 1]) {
					swap(data, in, in + 1);
					swapCount++;
				}
				loopCount++;
			}
		}
		System.out.println("交换次数:" + swapCount);
		System.out.println("比较次数:" + loopCount);
	}

	/**
	 * 我的选择排序 <br>
	 * <li>还是经典的厉害,虽然效果一样,思路一样,但是我就是多了个min变量来保存每次循环的最小值。实际这个值对排序是无意义的。 
	 * <li>但是,我没有想到,经过测试(10000个数字),我这个写法比经典的要快进40%左右。可能是,经典算法每次要定位然后在比较,我少了定位这一步。
	 * 
	 * <li>选择排序与冒泡比较来说,主要是少了交换次数,控制在N-1交换,比较次数一样。算法效率有提升(10000个数排序测试)。 <br> 
	 * <li>如果交换时间比比较时间更耗时,那么选择排序会比冒泡优越很多。
	 * 
	 * @param data
	 */
	public static void mySelectSort(int[] data) {
		int swapCount = 0;
		int loopCount = 0;
		for (int i = 0; i < data.length - 1; i++) {
			int min = data[i];
			int minIndex = i;
			for (int j = i; j < data.length; j++) {
				if (min > data[j]) {
					min = data[j];
					minIndex = j;
				}
				loopCount++;
			}
			swap(data, i, minIndex);
			swapCount++;
		}
		System.out.println("交换次数:" + swapCount);
		System.out.println("比较次数:" + loopCount);
	}

	/**
	 * 选择排序(书中经典写法)
	 * 
	 * @param data
	 */
	public static void selectSort(int[] data) {
		int swapCount = 0;
		int loopCount = 0;

		int out, in, min;
		for (out = 0; out < data.length - 1; out++) {
			min = out;
			for (in = out; in < data.length; in++) {
				if (data[min] > data[in]) {
					min = in;
				}
				loopCount++;
			}
			swap(data, out, min);
			swapCount++;
		}

		System.out.println("交换次数:" + swapCount);
		System.out.println("比较次数:" + loopCount);

	}

	/**
	 * 我的插入排序<br>
	 * <li>只能一个郁闷了得,我只是理解了算法的思路,写法太龌龊了。不加注释估计看不懂。</li> 
	 * <li>还是经典的看起舒服。可读性强,好理解。</li>
	 * 
	 * <li>插入排序在原始数据完全无序的情况下比较和复杂和冒泡,选择排序无限接近O(N^2) 
	 * <li>原始数据基本有序或部分有序的情况下,因为内层循环判断会减少,所有无限接近O(N)
	 * 
	 * @param data
	 */
	public static void myInsertSort(int[] data) {
		int swapCount = 0;
		int loopCount = 0;

		for (int i = 1; i < data.length; i++) { // 从第2个元素开始向前比较
			int flag = data[i]; // 开始比较的基准元素
			int targetIndex = 0; // 默认没有找到插入位置,则插入到第1个
			// 从开始比较的元素前面一个开始比较,找到比基准元素小的元素,
			// 以该元素的前面个位置作为插入点,其它元素依次后移。
			// 如果查到到起点都没有比基准元素小的值,则插入到第1个元素的为位置
			for (int j = i - 1; j >= 0; j--) {
				if (flag >= data[j]) {
					// 找到比基准元素小的值,保持插入点,退出循环
					targetIndex = j + 1;
					break;
				} else {
					// 没有找到比基准元素小的值,则向后移动
					data[j + 1] = data[j];
					swapCount++;
				}
				loopCount++;
			}
			// 插入
			data[targetIndex] = flag;
			swapCount++;
		}

		System.out.println("交换次数:" + swapCount);
		System.out.println("比较次数:" + loopCount);
	}

	/**
	 * 经典插入算法
	 * 
	 * @param data
	 */
	public static void insertSort(int[] data) {
		int swapCount = 0;
		int loopCount = 0;

		for (int out = 1; out < data.length; out++) {
			int flag = data[out];
			int in = out;
			while (in > 0 && data[in - 1] >= flag) {
				data[in] = data[in - 1];
				in--;
				loopCount++;
				swapCount++;
			}
			data[in] = flag;
			swapCount++;
		}

		System.out.println("交换次数:" + swapCount);
		System.out.println("比较次数:" + loopCount);
	}

	/**
	 * 交换数组中两个元素的值
	 * 
	 * @param data
	 * @param i
	 * @param j
	 */
	private static void swap(int[] data, int i, int j) {
		int temp = data[i];
		data[i] = data[j];
		data[j] = temp;
	}

	private static void printArray(String message, int[] data) {
		System.out.println(message + ArrayUtils.toString(data));
	}

}
 

 

分享到:
评论

相关推荐

    算法设计与分析-排序算法性能分析-要求pdf 报告文档 c++源代码 preppt

    选择排序 冒泡排序 插入排序 合并排序 快速排序算法原理及代码实现 不同排序算法时间效率的经验分析方法 验证理论分析与经验分析的一致性 void Init_Random();//数组随机数初始化函数声明 void Show_Array();//展示...

    算法设计与分析-排序算法源代码

    算法设计与分析-排序算法c++源代码 仅做参考,copy冲查重塔峰 选择排序 冒泡排序 插入排序 合并排序 快速排序算法原理及代码实现 不同排序算法时间效率的经验分析方法 验证理论分析与经验分析的一致性 void Init_...

    插入,选择排序的链表实现及快速,希尔,冒泡排序算法实现合集

    选择排序是一种不稳定的排序算法,其基本思想是在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。这个过程...

    常见的各种排序算法排序

    选择排序是一种简单直观的排序算法,它的基本思想是在每一趟排序中,找到剩余未排序部分中最小(或最大)的元素,放到已排序部分的末尾。选择排序是不稳定的排序方法,即相等的元素可能会改变它们原有的相对顺序。...

    九种排序算法

    这四种排序算法包括:选择排序、直接插入排序、冒泡排序和希尔排序。 ### 1. 选择排序(Select Sort) #### 算法原理: 选择排序的基本思想是从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始...

    排序算法汇总

    #### 二、排序算法的基本概念 1. **稳定排序和非稳定排序** - **稳定排序**:如果一个排序算法能够保证所有相等的元素在排序后的相对位置不变,则称其为稳定排序。例如,若数组排序前为`a1,a2,a3,a4,a5`,其中`a2...

    四种基本排序算法

    ### 四种基本排序算法及二分查找 在计算机科学领域,排序算法是十分重要的基础知识之一,它们不仅在数据管理中扮演着核心角色,还广泛应用于各种编程问题中。本文将详细介绍五种基本的排序算法:冒泡排序、选择排序...

    选择排序-插入排序-快速排序-冒泡排序

    在C语言环境下,快速排序.c、insert_sort.c、select_sort.c和maopao_sort.c这四个文件分别对应快速排序、插入排序、选择排序和冒泡排序的源代码实现,读者可以通过阅读和学习这些代码来加深对这些排序算法的理解。

    C语言---内部排序算法的性能分析.zip

    (2)需要实现起泡排序(Bubble)、直接插入排序(Insert)、简单选择排序(Select)、快速排序(Quick)、希尔排序(Shell)、堆排序(Heap)几种基本排序算法。 (3)需要实现数据的插入操作,将五组数据存入...

    经典排序算法,有选择排序,冒泡排序,交换排序,谢尔排序,插入排序基数排序

    根据给定的文件信息,我们将深入探讨几种经典的排序算法,包括选择排序、冒泡排序、交换排序、希尔排序、插入排序以及基数排序。这些算法在计算机科学领域内有着广泛的应用,各自具有独特的特点和适用场景。 ### 1....

    java 四种简单排序算法讲解和代码

    //冒泡 Bubble bubble=new Bubble();... Insert is=new Insert(); is.sort(arr); print(arr);//打印结果 //快速 Quick qs=new Quick(); qs.sort(0,arr.length-1,arr); print(arr);//打印结果

    C语言常用排序算法

    根据给定文件的信息,本文将详细介绍C语言中的几种常用排序算法,包括冒泡排序、选择排序、插入排序、快速排序以及希尔排序。 ### 一、冒泡排序(Bubble Sort) 冒泡排序是一种简单的排序算法。它重复地遍历待排序...

    数据结构实验报告排序

    选择排序的基本思想是在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 ...

    排序 快排,shell,insert,select 等

    ### 排序算法知识点 根据提供的代码片段及标题、描述,可以提炼出以下关于排序算法的知识点: #### 1. 插入排序(Insert Sort) 插入排序是一种简单直观的比较排序算法。它的工作原理是通过构建有序序列,对于未...

    C语言排序算法汇总

    冒泡排序是最简单的排序算法之一,其基本思想是重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。...

    C-C++排序算法总结

    根据给定的信息,本文将对几种常见的排序算法进行详细的总结与解释,包括冒泡排序、选择排序、希尔排序以及插入排序。这些算法都是基础且重要的数据处理方法,在计算机科学领域有着广泛的应用。 ### 一、冒泡排序 ...

    各种排序算法

    //cout&lt;&lt;"select_sort"; //select_sort(array,10); //cout&lt;&lt;"bubble_sort"; //bubble_sort(array,10); //cout&lt;&lt;"insert_sort"; //insert_sort(array,10); //cout; //heap_sort(array,10); //cout; //...

    常用数据结构排序算法总结

    本文将对几种常见的排序算法进行详细的解析,包括冒泡排序、交换排序、选择排序和插入排序,这些都是在面试、笔试和学习过程中常遇到的基本排序方法。 1. **冒泡排序**: 冒泡排序是一种直观且基础的排序算法,...

    常见排序算法总结

    尽管现代编程语言和库提供了高效且可靠的排序方法,但理解基本排序算法的工作原理仍然对程序员来说至关重要。本文将详细介绍几种常见的排序算法,并分析它们的基本思想、工作原理以及效率。 #### 二、冒泡排序 **...

    排序算法实验

    根据给定文件的信息,本文将对几种常用的排序算法进行详细解析与对比,这些算法包括:插入排序(Insert Sort)、冒泡排序(Bubble Sort)、快速排序(Quick Sort)以及选择排序(Selection Sort)。此外,还将通过...

Global site tag (gtag.js) - Google Analytics