各种排序算法Java实现

校招快要开始了,复习一下以前的排序知识,下面的代码都是以前写的,今天翻出来又重新看了一下,贴上来。也算是复习吧。

插入排序,稳定排序(稳定是指相同的两个数在排序之后它们的相对位置不变。):

//插入排序
	 public static void insertSort(int[] a){
		 int len = a.length;
		//遍历数组
		 for(int i=1;i<len;i++){
			 int temp = a[i];
			 int j=i-1;
			 while(j>=0&&temp<a[j]){
				//循环比较插入,即向后移动...
				 a[j+1]=a[j];
				 j--;
			 }
			 a[j+1]=temp;
		 }
	 }

希尔排序,不稳定的排序

 //希尔排序,本质上是插入排序
		public static void shellSort(int[] a){
			int[] s = {1,3,5};
			int j,temp;
			int k=0;
			//x为希尔间隔参数,最外环的遍历,以希尔间隔参数遍历三次,当然希尔参数可以有很多,x为希尔间隔参数
			for(int x=s[2];x>=0;x-=2){
				//第二层循环:以当前的希尔变量循环一次一部分数组
				while(k<x){
					//以下是插入排序
					//希尔间隔参数里面的每一次插入排序
					for(int i=x+k;i<a.length;i+=x){
						temp = a[i];
						j = i-x;
						while(j>=k && a[j]>=temp){
							a[j+x] = a[j];
							j-=x;
						}
						a[j+x] = temp;
					}
					k++;
				}
				k=0;
			}
			
		}
快速排序,其实是冒泡排序的改进,是一种不稳定排序:

//快速排序
	public static void quick(int[] a,int i,int j){
		if(i<j){
			int q = quickSort(a,i,j);
			 quick(a,i,q-1);
			 quick(a,q+1,j);
		}
		return;
	}
	
	////快速排序i不可能等于数组的最后一个下标,而且最后i一定等于j,并且下标为i的值就是temp
	public static int quickSort(int[] a,int i,int j){
		if(a.length==1){
			return 0;
		}
		int temp  = a[i];
		//前后相互比较,把大于temp的值放在数组的后面,小于temp的值反正前面
		while(i<j){
			//当从后面比较时,大于temp就一直让自减
			while(temp<a[j]){
				j--;
			}
			//如果下降到i==j的时候则不要交换了
			if(i!=j){
				swap(a,i,j);
				i++;
			}
			//同上
			while(temp>a[i]){
				i++;
			}
			if(i!=j){
				swap(a,i,j);
				j--;
			}
		}
		return i;
	}
	
	public static void swap(int[] a,int i,int j){
		int temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}

选择排序,不是一个稳定的排序算法

public static void selectSort(int[] a){
		int min;
		for(int i=0;i<a.length-1;i++){
			min = i;
			for(int j = i+1;j<a.length;j++){
				//通过与临时最小的比较,得到当前的最小
				if(a[j]<a[min]){
					min = j;
				}
			}
			swap(a,i,min);
		}
	}
冒泡排序,稳定排序:

	 public static void bubbleSort(int[] a){
			for(int i=a.length-1;i>0;i--){
				for(int j=0;j<i;j++){
					if(a[j]>a[j+1]){
						swap(a,j,j+1);
					}
				}
			}
		}

归并排序,稳定排序:
public static void mergeSort(int[] a){
		mergeSort(a,0,a.length-1);
	}
	//递归合并
	public static void mergeSort(int[] a,int first,int last){
		int mid = (first+last)/2;
		if(first<last){
			mergeSort(a,first,mid);
			mergeSort(a,mid+1,last);
			merge(a,first,mid,last);
		}
	}
	//其中first,mid,last都是在数组中的索引,last==a.length-1
	public static void merge(int[] a,int first,int mid,int last){
		int[] c = new int[last-first+1];
		int aIndex = first;
		int cIndex =0;//c的索引
		int bIndex = mid+1;
		while(aIndex<mid+1 && bIndex<last+1){
			if(a[aIndex]<a[bIndex]){
				c[cIndex++] = a[aIndex++];
			}else{
				c[cIndex++] = a[bIndex++];
			}
		}
		if(aIndex<=mid){
			while(aIndex<=mid){
				c[cIndex++] = a[aIndex++];
			}
		}
		if(bIndex<=last){
			while(bIndex<=last){
				c[cIndex++] = a[bIndex++];
			}
		}
		//c排序完成之后,把c中的值都赋给a,改变a的值以便循环递归
		for(int i=0;i<c.length;i++){
			a[first+i] = c[i];
		}
		
	}
堆排序,不是稳定的排序,非常适合大数据(如百万级别的),因为快速排序和归并排序都是基于递归的,有可能发生堆栈溢出:

	//堆排序核心算法
	//调用了建堆函数和以i为最大堆的函数
	public static void heapSort(int[] a){
		buildHeap(a);
		int heapSize = a.length;
		for(int i=a.length-1;i>=0;i--){
			 swap(a,0,i);
			 heapSize--;
			 maxHeap(a,0,heapSize);
		}
	}
	
	//建造一个大顶堆,从索引a.length/2-1开始,对每个元素使用maxHeap,即可以建立一个大顶堆
	public static void buildHeap(int[] a){
		int lag = (int)Math.ceil(a.length/2)-1;
		for(int i=lag;i>=0;i--){
			maxHeap(a,i,a.length);
		}
	}
	
	//以i为最大堆,i在输入的时候,让i节点的值比他的左右子女都要大
	public static void maxHeap(int[] a,int i,int heapSize){
		//因为堆是从1开始算的,数组是从0开始算的,所以在外面是以数组的形式i传进来要加1
		int left = 2*(i+1)-1;
		int right = 2*(i+1);
		int large;
		if(left<heapSize&& a[left]>a[i]){
			large = left;
		}else{
			large = i;
		}
		if(right<heapSize && a[right]>a[large]){
			large = right;
		}
		if(large!=i){
			swap(a,i,large);
			maxHeap(a,large,heapSize);
		}
	}
以下从网上摘抄的各种排序的一些比较:


不过其中归并的额外空间应该是O(n)

参考:

博客:http://blog.csdn.net/hkx1n/article/details/3922249

图解Java数据结构和算法

06-21
1.算法是程序的灵魂,优秀的程序在对海量数据处理时,依然保持高速计算,就需要高效的数据结构和算法支撑。2.网上数据结构和算法的课程不少,但存在两个问题:1)授课方式单一,大多是照着代码念一遍,数据结构和算法本身就比较难理解,对基础好的学员来说,还好一点,对基础不好的学生来说,基本上就是听天书了2)说是讲数据结构和算法,但大多是挂羊头卖狗肉,算法讲的很少。 本课程针对上述问题,有针对性的进行了升级 3)授课方式采用图解+算法游戏的方式,让课程生动有趣好理解 4)系统全面的讲解了数据结构和算法, 除常用数据结构和算法外,还包括程序员常用10大算法:二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、马踏棋盘算法。可以解决面试遇到的最短路径、最小生成树、最小连通图、动态规划等问题及衍生出的面试题,让你秒杀其他面试小伙伴3.如果你不想永远都是代码工人,就需要花时间来研究下数据结构和算法。教程内容:本教程是使用Java来讲解数据结构和算法,考虑到数据结构和算法较难,授课采用图解加算法游戏的方式。内容包括: 稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。学习目标:通过学习,学员能掌握主流数据结构和算法的实现机制,开阔编程思路,提高优化程序的能力。
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值