常见排序集合(冒泡排序,选择排序,直接插入排序,二分插入排序,快速排序,希尔排序,归并排序)

一下是一些常见的排序算法:

交换元素(后面算法都有用到):

// 交换元素
	private static void swap(int[] a, int i, int j) {
		int temp;
		temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}

冒泡排序(有优化):

// 冒泡排序(优化①,②,③,④)
	private static void bubbleSort(int[] a) {
		boolean flag = false;// ①表示整个序列是无序的
		for (int i = 0; i < a.length - 1; i++) {
			flag = true; // ②假设:此时序列是有序的
			for (int j = 0; j < a.length - i - 1; j++) {
				if (a[j] > a[j + 1]) {
					swap(a, j, j + 1);
					flag = false;// ③只要出现了交换位置,则上面假设不成立
				}
			}
			// ④上面假设成立(即序列有序),直接返回,不需要再循环冒泡了
			if (flag) {
				return;
			}
		}
	}

选择排序:

// 选择排序
	private static void selectSort(int[] a) {
		for (int i = 0; i < a.length - 1; i++) {
			for (int j = i + 1; j < a.length; j++) {
				if (a[i] > a[j]) {
					swap(a, i, j);
				}
			}
		}
	}

直接插入排序:

// 直接插入排序
	private static void inserteSort(int[] a) {
		for (int i = 0; i < a.length - 1; i++) {
			int temp = a[i + 1];
			int j = i;
			while (a[j] > temp) {
				a[j + 1] = a[j];
				j--;
				if (j < 0) {
					break;
				}
			}
			a[j + 1] = temp;
		}
	}

二分插入排序:

// 二分插入排序
	private static void binaryInsertSort(int[] a) {
		for (int i = 0; i < a.length - 1; i++) {
			int low = 0;
			int high = i;
			int temp = a[i + 1];
			int mid;
			// 在low和high之间的区域内进行二分法,以确定新元素的插入位置
			while (low <= high) {
				mid = (low + high) / 2;
				if (a[mid] > temp) {// 若带插入的数小于中间元素a[mid],则目标落在左半区
					high = mid - 1;
				} else {// r若带插入的数大于等于中间元素a[mid],则目标落于右半区
					low = mid + 1;
				}
			}
			// 搜索的最后一个小区间的high位置(即是查找目标,因此新元素的插入位置(即high+1)
			// 把原来从high到i范围内的元素依次后移一个位置
			for (int j = i; j > high; j--) {
				a[j + 1] = a[j];
			}
			a[high + 1] = temp;
		}
	}

希尔排序:

// 希尔排序
	private static void shellSort(int[] a) {
		// 进行分组,初始步长设为数组长度的的一半(即n/2),然后依次减半,直到最后取1
		for (int gap = (a.length + 1) / 2; gap > 0;) {
			// 组内排序
			for (int i = 0; i < a.length - gap; i++) {// 定位到每一个元素
				for (int j = i; j < a.length - gap; j += gap) {
					if (a[j] > a[j + gap]) {
						swap(a, j, j + gap);
					}
				}
			}
			// for循环修正
			if (gap > 1) {
				gap = (gap + 1) / 2;
			} else if (gap == 1) {
				break;
			}
		}
	}

快速排序(优化):

// 快速排序
	private static void quickSort(int[] a, int l, int r) {
		if (l < r) {
			int p = partition(a, l, r);
			quickSort(a, l, p - 1);
			quickSort(a, p + 1, r);
		}
	}

	private static int partition(int[] a, int l, int r) {
		// 优化随机取枢轴
		int rand = (int) (Math.random() * (r - l));
		swap(a, l, l + rand);
		int i = l;// 第一个元素为枢轴
		int j = r + 1;
		int x = a[i];
		while (true) {
			while ((a[++i] < x) && i < r) {
			}
			;// 定位指针i,找到比x大的元素
			while ((a[--j] > x)) {
			}
			; // 定位指针j
			if (i >= j) {
				break;
			}
			swap(a, i, j);
		}
		swap(a, l, j);// 枢轴a[l]要换到中间位置
		return j;
	}

归并排序:

// 归并排序
	private static void mergeSort(int[] a, int l, int r) {
		if (l < r) {//至少两个元素
			int mid = (r + l)/2;
			//把序列拆分成两个子序列[left,mid]和[mid+1,right]
			//同时还要对分解后的子序列分别进行递归“归并排序”
			mergeSort(a, l, mid);
			mergeSort(a, mid + 1, r);
			//把两个已经排好序的数组进行归并
			int[] b = new int[a.length];
			merge(a, b, l, mid, r);
			copyArray(a, b, l, r);
		}
	}

	private static void copyArray(int[] a, int[] b, int l, int r) {
		for(int i=l;i<=r;i++){
			a[i]=b[i];
		}
	}

	//把两个已经排好的子序列(a[letf,mid]he a[mid+1,right])合并成一个b[left,right]
	private static void merge(int[] a, int[] b, int left, int mid, int right) {
		int r=left;
		int p=mid+1;
		int k=left;
		while(r<=mid&&p<=right){
			if(a[r]<=a[p]){
				b[k++]=a[r++];
			}else{
				b[k++]=a[p++];
			}
		}
		//此时,肯定有一个子序列中的元素全部移动到b[]数组中,因此,需要把未移完的子序列当中的所有剩余的元素直接拷到数组b[]中即可
		if(r>mid){//左子序已经完成,因此剩下的是有序列,对拷有序列中的剩余元素即可
			for(int i=p;i<=right;i++){
				b[k++]=a[i];
			}
		}else{//对拷左子序中的剩余元素
			for(int i=r;i<=mid;i++){
				b[k++]=a[i];
			}
		}
	}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-24 04:25:38

常见排序集合(冒泡排序,选择排序,直接插入排序,二分插入排序,快速排序,希尔排序,归并排序)的相关文章

经典排序:冒泡排序+选择排序 小结

经典排序:冒泡排序+选择排序 例 FJUTOJ 1842 冒泡排序 原理是取相邻两个数进行大小比较,判断是否交换. 以从小到大排序为例,冒泡排序就像气泡一样,最小的数慢慢浮上来,最大的数慢慢沉下去.那么完整从头到尾做一次之后最后一位就是原序列中最大的数字了.然后只需要对1~(n-1)个数字进行排序,完成后倒数第二个数字也为原序列的1~n-1元素中最大的值.如此重复,进行n-1次一定能完成排序.参考代码: 1 #include <stdio.h> 2 void BubbleSort(int *,

快速排序 &amp;&amp; 希尔排序 &amp;&amp; 插入排序

1. 快速排序 不稳定的排序. 平均(与最好情况)时间复杂度:O(nlgn)   |  最坏情况时间复杂度(元素有序,递归栈为 O(n)):O(n2) 适合的数据结构:数组,双向链表. #include <stdio.h> #include <stdlib.h> int partition(int data[], int low, int high) { int value = data[low]; // can be done randomly while(low < hi

简单排序算法 冒泡排序 选择排序 插入排序

冒泡排序: 总体思路:对未排序的各个元素,依次比较两个元素,如果这两个元素为逆序(与想要的顺序相反),则交换这两个元素. 这样可以有两种排序的思路: 思路一: 固定位置排序:比如有一个未排序队列,下标依次为0,1,2,.....N-1, 第一轮排序:首先固定位置0,将下标为0的元素依次和下标为1.下标为2.....下标为N-1的元素相比较,若相比较的两个元素为逆序,则交换这两个元素,这样第一轮排序完之后,位置为0的元素,就是最大的(最小的). 第二轮排序:首先固定位置1,将下标为1的元素依次和下

排序之插入排序:直接插入和希尔排序

一.插入排序 1.思想:原理类似抓扑克牌,在有序表中进行插入和查找,插入合适的位置时,之后的元素需要往后移动 2.时间复杂度: 最好:O(N),正序情况,只有比较时间,无移动时间 最坏:O(N2),逆序情况 平均:O(N2) 3.辅助空间:O(1) 4.稳定性:稳定 5.适用场合:适用于初始序列基本有序的情况,或者n小的时候,插入排序效率高 1 public static void insertSort(int[] a) { 2 int target,i,j; 3 for(j = 1;j<a.l

直接插入排序/二分插入排序/希尔排序

---恢复内容开始--- 插入排序是在源数据已经有序的情况下进行排序.时间复杂度O(N^2),稳定的 直接插入排序 代码如下 public static int[] insertSort(int [] a){ if(a==null||a.length==0){ return a;} for(int i=1;i<a.length;i++){ for(int j=i-1;j>=0&&a[j]>a[j+1];j--) swap(a,j,j+1);//满足前一个大于后一个才进行交

C语言-排序方法(冒泡排序,选择排序,快速排序, 插入排序 )

/* 排序算法 */ #include <stdio.h> //冒泡排序 void Bubble_sort(int *p_val, int size) { int j = 0; int i = 0; for (i = 0;i < size - 1;i++) { for (j = i;j < size - 1;j++) { if (*(p_val + j) > *(p_val + j + 1)) { *(p_val + j) ^= *(p_val + j + 1); *(p_v

七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)

 写在前面: 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的任意序列,重新排列成一个按关键字有序的序列.因此排序掌握各种排序算法非常重要.对下面介绍的各个排序,我们假定所有排序的关键字都是整数.对传入函数的参数默认是已经检查好了的.只是简单的描述各个算法并给出了具体实现代码,并未做其他深究探讨. 基础知识: 由于待排序的记录数量不同,使得排序过程中设计的存储器不同,可将排序方法分为两大类:一类是内部排序,指的是待排序记录存放在计算机随机存储器中进行的排序过程.另一类是外部排序,

【数据结构与算法】内部排序之一:插入排序和希尔排序的N中实现(不断优化,附完整源码)

转载请注明出处:http://blog.csdn.net/ns_code/article/details/20043459   前言 本来想将所有的内部排序总结为一篇博文,但是随着研究的深入,还是放弃了这个念头,斟前酌后,还是觉得分开来写比较好,具体原因,看完本篇博文也就自然明了了. 本篇文章主要探讨插入排序和希尔排序,之所将二者放在一起,很明显,是因为希尔排序是建立在插入排序的基础之上的.     注:以下各排序算法的N种实现方法大部分都是我根据算法思想,自己写出来的,或者是参考其本身的经典实

插入排序算法之希尔排序

一.前沿: 希尔排序(Shell Sort)的名称源于它的发明者Donald Shell,该算法是冲破了二次元时间屏障的算法之一.它通过比较相距一定间隔的元素工作,各趟所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟为止,因此希尔排序有时也叫做缩减增量排序(diminishing increament sort). 二.详细步骤: 希尔排序使用一个序列h1,h2,......ht 叫做   增量序列,只要h1=1,任何增量序列都是可行的,在使用hk的一趟增量序列后,数组中任何a[i]

对c语言系统库函数、堆排序、希尔排序、折半插入排序、快速排序消耗时间的比较

#include <stdio.h> #include <time.h> #define N 100000 /*库比较函数:qsort(int *base,int n,int struct_size,int (*compare)(const void *,const void *))中的比较函数*/ int compare(const void *first, const void *second) { if (*(int *)first > *(int *)second)/