数组七大经典排序算法(冒泡、插入、希尔、快排、选择、归并、堆)Java实现

简介

这是一份常用经典排序算法的Java代码实现,可运行。

算法包括:冒泡排序、插入排序、希尔排序、快速排序、选择排序、归并排序、堆排序。

复杂度

算法复杂度,稳定性:
数组七大经典排序算法(冒泡、插入、希尔、快排、选择、归并、堆)Java实现_第1张图片
忘记说希尔排序了~

希尔排序是不稳定的。因为,虽然一次插入排序是稳定的,但是分区后的插入可能导致不同分区之间的数相对位置发生改变,因此最终是不稳定的。

希尔排序的时间复杂度没有明确的说法,有的说平均复杂度是O(nlogn),有的说是O(n1.3),总之就是比O(n2)小啦。

希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些

代码

话不多说,上代码:

package test1;

public class Test {
	/**
	 * 交换数组中两个数
	 * @param nums
	 * @param i
	 * @param j
	 */
	public static void swap(int nums[],int i,int j){
		int temp;
		temp = nums[i];
		nums[i] = nums[j];
		nums[j]=temp;
	}
	/**
	 * 冒泡排序
	 * @param nums
	 */
	public static void bubbleSort(int nums[]){
		for(int i = 0;inums[j+1]){
					swap(nums,j,j+1);
				}
			}
		}
	}
	/**
	 * 改进的冒泡排序
	 * @param nums
	 */
	public static void improvedBubbleSort(int nums[]){
		for(int i = 0;inums[j+1]){
					swap(nums,j,j+1);
					isChanged = true;
				}
			}
			if(!isChanged){//如果没有发生交换,则已经有序,直接结束排序
				break;
			}
		}
	}
	/**
	 * 插入排序
	 * @param nums
	 */
	public static void insertSort(int nums[]){
		int len = nums.length;
		for(int i = 1;i=0&&nums[j]>temp;j--){
					nums[j+1] = nums[j];
				}
				nums[j+1] = temp;//赋值
			}
		}
	}
	/**
	 * 引入二分查找的插入排序
	 * @param nums
	 */
	public static void insertBinarySort(int nums[]){
		int len = nums.length;
		for(int i = 1;inums[mid]){//如果当前值大于中间位置的值,则区间改为[mid+1,h]
						low = mid+1;
					}else{//如果当前值小于中间位置的值,则区间改为[low,mid-1]
						h = mid-1;
					}
				}
				//找到位置(就是low)后,从后向前移动数组,以腾出位置
				for(int j = i;j>low;j--){
					nums[j] = nums[j-1];
				}
				nums[low] = temp;//赋值
			}
		}
	}
	/**
	 * 希尔排序
	 * @param nums
	 */
	public static void shellSort(int nums[]){
		int len = nums.length;
		for(int gap = len/2;gap>0;gap/=2){//gap每次减半
			for(int i = 0;i=gap&&temptemp){
				nums[i] = nums[k];
				i = k;//记录父节点的位置,最终要落到的位置
			}else{//如果子节点小于父节点,则调整结束
				break;
			}
		}
		//将当前父节点的值,最终落位入座
		nums[i] = temp;
	}
	/**
	 * 堆排序,升序,最大堆
	 * 通过不断把根节点(最大值)放到最后一个节点处,
	 * 实现数组从小到大排序
	 * @param nums
	 */
	public static void heapSort(int nums[]){
		int len = nums.length;
		// build heap
		for(int i = len/2-1;i>=0;i--){
			//从最后一个非叶节点开始调整,使之满足最大堆
			adjustHeap(nums,i,len);
		}
		// exchange and adjust
		for(int j = len-1;j>=0;j--){
			//交换根节点与最后一个节点,通过不断把根节点(最大值)放到最后一个节点处,
			//实现数组从小到大排序
			swap(nums,0,j);
			//调整剩下的节点,使它们满足最大堆
			adjustHeap(nums,0,j);//j是当做长度传过去的,所以,去掉了最后一个节点
		}
		
	}
	
	public static void main(String[] args) {
		
		int nums[] = {2,4,5,7,2,3,4};
		System.out.println("-----排序前-----");
		for(int n:nums){
			System.out.println(n);
		}
//		bubbleSort(nums);//冒泡排序
//		improvedBubbleSort(nums);//改进的冒泡排序
//		insertSort(nums);//插入排序
//		insertBinarySort(nums);//二分插入排序
//		shellSort(nums);//希尔排序
//		selectSort(nums);//选择排序
//		quickSort(nums);//快速排序
//		mergeSort(nums);//归并排序
		heapSort(nums);//堆排序
		
		System.out.println("------排序后-----");
		for(int n:nums){
			System.out.println(n);
		}
		
 }

}

补充:

快速排序的思想:分治法

  • 1.先从数组中取出一个数作为基准数。
  • 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
  • 3.再对左右区间重复第二步,直到各区间只有一个数。

参考文章
堆排序讲解 https://www.cnblogs.com/chengxiao/p/6129630.html
各算法的性能及复杂度讲解 https://segmentfault.com/a/1190000004994003

你可能感兴趣的:(java,传统算法)