首页 > 代码库 > 数据结构精要------冒泡与直接排序算法

数据结构精要------冒泡与直接排序算法

作为程序员的我们在程序开发的时候经常会用到一些简单的排序算法,例如:对数组进行快速排序;要实现这些就需要运用到数据结构排序算法的知识,那么熟练使用和掌握排序算法对于开发人员来说是百利而无一害。同时记录一下知识点也是自己对自己的进一步巩固总结:

那么何为排序算法呢?

      排序是计算机内经常进行的一种操作,其目是一组 “无序 ”的记录序列调整为 “有序 ”的记 录序列。排序分内排序和外排序。

那么何为内排和外排呢?

      内排序 :指在排序 期间数据对象全部存放在内存排序。

      外排序 :指在排序期间全部对象个数太多, 不能同时存放内存,必须根据派寻过程的要求,不断在内、外存之间移动的排序。

      内排序的方法有许多种,按所用策略不同,可归纳为五类:插入排序、选择排序、交换排序、归并排序和分配排序。

      --交换排序 主要包括冒泡排序 和 快速排序

      --插入排序 主要包括直接插入排序 和 希尔排序

      --选择排序 主要包括直接选择排序 和 堆排序

      --归并排序 主要包括二路归并(常用的归并排序)和 自然归并排序

      --分配排序 主要包括 箱排序 和 基数排序

稳定排序:假设在待排序的文件中,存在两个或两个以上的记录具有相同的关键字,在用某种排序法排序后,若这些相同关键字的元素的相对次序仍然不变,则这种排序方法是稳定的。 其中冒泡,插入,基数,归并属于稳定排序; 选择,快速,希尔,堆属于不稳定排序。

时间复杂度是衡量算法好坏的最重要的标志。 排序的时间复杂度与算法执行中的数据比较次数与数据移动次数密切相关。


下面我们一步一步用代码来实现:首先实践交换排序的两种

-----冒泡排序

package com.sort;

/**
 * 
 * 冒泡排序
 * @author weixing-yang
 * 
 *实现思路:
 * 首先比较 a[1]与 a[2]的值,若 a[1]大于 a[2]则交换两者的值,否则不变。
 * 再比较 a[2]与 a[3]的值,若 a[2]大于 a[3]则交换两者的值,否 则不变。
 * 再比较a[3]与a[4]的值,以此类推,最后比较a[n-1]与a[n]的值。
 * 这样一轮下来,a[n]的指一定是这组数据中最大的。
 * 在对a[1]~a[n-1]的用相同的方法处理一轮。
 * 共处理n-1轮后a[1]、a[2]、...,a[n]就以升序排列了。
 *
 */
public class BubbleSort {
	int temp = 0;
	int i,j,k;
	public void bubbleSort(int[] arr, int n){
		//将i设置为最后一对元素较小的下标
		for (i = n-1; i > 0; i = k) {
			for (k = j = 0; j < i; j++) {
				if(arr[j]>arr[j+1]){
					temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
					//如发生交换,记录较小的下标
					k = j;
				}
			}
		}
	}
}

-----快速排序

package com.sort;
/**
 * 
 * @author weixing-yang
 *
 *实现思路:
 *	通过一次排序将待排序对象分割成独立的两部分。
 *  其中一部分对象的关键码均比另一部分对象的关键码小。 
 *  再分别对这两部分子序列对象继续进行排序,以达到整个序列有序。
 */
public class QuickSort {
	
	public void quickSort(int[] arr,int l, int r){
		if(l >= r) 
			return;
		int i = l,           //从左到右的游标
			j = r+1;         //从右到左的游标
		int pivot = arr[l];  //以a[l]为支点
		int temp = 0;
		while(true){
			while (arr[++i] < pivot && i < r); //从左边找>=pivot的元素
			while (arr[--j] > pivot && j > l); //从右边找<=pivot的元素
			
			if(i >= j) break;
			temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;
		}
		//将支点a[l]与a[j]交换
		arr[l] = arr[j];
		arr[j] = pivot; 
		//递归
		if(l < r)
			quickSort(arr, l, j-1); // 左段快速排序 
		if(r > l)
			quickSort(arr, j+1, r); //右段快速排序
	}

}


-----测试函数

package com.sort;

public class Main {
	
	public static void main(String[] args){
		int[] array = {25, 36, 21, 45, 9, 40, 12, 34, 5, 55}; 
		int n = array.length;
		BubbleSort bubble = new BubbleSort();
		QuickSort quick = new QuickSort();
		long start = System.currentTimeMillis();
		//bubble.bubbleSort(array, n);//冒泡排序
		quick.quickSort(array, 0, n-1);//快速排序
		long end = System.currentTimeMillis();
		long sum = end - start;
		System.out.println("排序花费的总毫秒数:"+sum);
		for (int i = 0; i < array.length; i++) {
			System.out.print(array[i]+" ");
		}
	}
}

-----运行结果

排序花费的总毫秒数:0
5 9 12 21 25 34 36 40 45 55 

冒泡排序的时间复杂度是n2, 快速排序的时间复杂度是nlogn。

快速排序被认为是最快的内排序算法。当数据量少时,快速排序甚至不及简单的排序算法;此外,当数据本身已有序时,快速排序的效率极低。


@@------->>下篇继续实践插入排序的两种排序算法