用Java实现 一些面试要求的基本的排序算法
首先是插入排序:
个人思路:插入排序就是将一个无序的数组,从第一个开始,将下一个数插入到前面的有序数组中,使之前的数组依然有序。(我说的比较白话,因为是自己总结的)
比如数组 {1,5,3,4,5,8,2},从第二个开始,跟前面的数比较,如果小于前面的数,则交换。所以步骤如下:
{1,5,3,4,5,8,2}-->{1,3,5,4,5,8,2}-->{1,3,4,5,8,2}-->{1,3,4,5,8,2}-->{1,3,4,5,2,8}-->{1,3,4,2,5,8}-->{1,3,2,4,5,8}-->{1,2,3,4,5,8},最后排序完成。
算法实现为:
public class InsertSort { public static void main(String []args){ int a[] = {1,5,3,4,5,8,10,21,4,5,1}; insertSort(a); for(int i =0;i<a.length;i++){ System.out.print(a[i]+" "); } } public static void insertSort(int []a){ //从第二位开始 for(int i=1;i<a.length;i++){ //判断j是否大于零,这样避免a[j-1]越界 //从i开始,依次找前面的数,如果a[j]<a[j-1](后面的数大于前面的数), //则做交换,并且j--。 如果a[j]>a[j-1],则说明已经到了正确的位置,结束for循环 for(int j=i;j>0&&(a[j]<a[j-1]);j--){ int temp = a[j]; a[j] = a[j-1]; a[j-1] = temp; } } } }
希尔排序:希尔排序是先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<;…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
该方法实质上是一种分组插入方法。算法实现如下:
public class ShellSort { public static void main(String[] args) { int a[] = {1,5,3,4,5,8,10,21,4,5,1}; shellSort(a); for(int i =0;i<a.length;i++){ System.out.print(a[i]+" "); } } public static void shellSort(int a[]){ //i是增量的值 for(int i=a.length/2;i>2;i/=2){ //将前i个属于总量为i的不同分组做插入排序 for(int j=0;j<i;j++){ insertSort(a,j,i); } } insertSort(a,0,1); } public static void insertSort(int a[],int start,int inc){ //从start开始没意义,所以从第二个属于inc增量的组的开始算 for(int i=start+inc;i<a.length;i+=inc){ //用插入排序对其进行排序 当j>=inc时,是因为最小j就为inc,如果比inc还小,则会越界 for(int j=i;j>=inc&&(a[j]<a[j-inc]);j-=inc){ int temp = a[j]; a[j] = a[j-inc]; a[j-inc] = temp; } } } }
堆排序: 堆排序是用数组来表示一个完全二叉树。 具体思路就不写了,在算法代码中我直接用注释说明,原理大家找下资料就可以了
public class HeapSort { //本人用的是大根堆 public static void main(String[] args) { int a[] = {1,5,3,4,5,8,10,21,4,50,100,5,1}; heapSort(a); for(int i =0;i<a.length;i++){ System.out.print(a[i]+" "); } } //moveDown主要是用来将子树初始化,first相当于当前子树的根,last是最后一个节点的位置 public static void moveDown(int a[],int first,int last){ //得到左子树 因为数组是从零开始,所以需要加一 int largest = 2*first+1; while(largest<=last){//largest可以等于largest因为最后一位也可能是最大值,不能去除 //这个循环是为了找到最大节点的位置 //largest记录着当前最大节点的位置 while(largest<last&&(a[largest]<a[largest+1])) largest++; //找到最大的位置,判断是否比first处的值大,大的话,交换值,同时因为移动了子树的节点 //largest为根的子树的堆混乱了,需要重新建堆,所以将根first设为largest //largest依旧取根的左子树 //如果小的话,则说明根处的值已经是最大的了,跳出循环 if(a[first]<a[largest]){ int temp = a[first]; a[first] = a[largest]; a[largest] = temp; first = largest; largest = 2*first+1; }else{ largest = last+1; } } } public static void heapSort(int a[]){ //i=a.length/2-1,得到最后一个叶子节点的父亲,从最后的一个子树开始进行建堆 for(int i=a.length/2-1;i>=0;i--){ moveDown(a,i,a.length-1); } //从最后一个开始,依次将最大的数交换到最后, for(int i=a.length-1;i>0;i--){ int temp = a[0]; a[0] = a[i]; a[i] = temp; //然后在将堆重新构造 moveDown(a,0,i-1); } } }
冒泡排序:最基本的排序,基本上大家都会0 0,就是依次选第i位(i<n),并从后面开始,将i后的最小的数冒到第i位。
算法实现:
public class maopao { public static void main(String []args){ int a[] = {1,5,3,4,5,8,10,21,4,5,1}; mao(a); for(int i =0;i<a.length;i++){ System.out.print(a[i]+" "); } } public static void mao(int a[]){ //i从0开始 for(int i=0;i<a.length;i++){ //从最后一位开始,如果小于前面的数,则交换 for(int j=a.length-1;j>i;j--){ if(a[j]<a[j-1]){ int temp = a[j]; a[j] = a[j-1]; a[j-1] = temp; } } } } }
选择排序:
数组从i(0<i<n)开始,需要一个辅助数据,temp,存储i之后的最小的数的位置,如果选择之后,temp!=i,则交换temp和i的数,i++;
算法如下:
public class SelectSort { public static void main(String []args){ int a[] = {1,5,3,4,5,8,10,21,4,5,1}; selectSort(a); for(int i =0;i<a.length;i++){ System.out.print(a[i]+" "); } } public static void selectSort(int a[]){ //存储当前最小的数的位置 int temp; for(int i=0;i<a.length;i++){ //temp刚开始为i temp = i; for(int j=i+1;j<a.length;j++){ //如果存在比他小的数,则temp=j if(a[temp]>a[j]){ temp = j; } } //如果temp!=i,说明后面有比i位上的数更小的数 //交换temp和i位的数 if(temp!=i){ int t = a[i]; a[i] = a[temp]; a[temp] = t; } } } }
快排: 设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
算法如下:
public class quickSort { public static void main(String[] args) { int a[] = {1,5,3,4,5,8,10,21,4,5,1}; quickSort(a,0,a.length-1); for(int i =0;i<a.length;i++){ System.out.print(a[i]+" "); } } //得到中间位置,这个位置的前面的数都小于他,后面的数都大于他 public static int partition(int a[],int low,int high){ //以low处为基准点 int paior = a[low]; while(low<high){ //从后看,如果high大于等于基准点,则high-- while(low<high&&a[high]>=paior) high--; //这个时候high处的值小于等于基准点,将值付给low a[low] = a[high]; //从前面看,如果low小于基准点的值,则low++ while(low<high&&a[low]<=paior) low++; //这个时候low处的值大于等于基准点,将值付给high a[high] = a[low]; } //最后将low处附上基准点的值,low就是基准点的位置,返回low a[low] = paior; return low; } public static void quickSort(int a[],int low,int high){ if(low<high){ //找到基准点 int part = partition(a, low, high); //将基准点前面的数在做排序 quickSort(a, low, part-1); //将基准点后面的数在做排序 quickSort(a, part+1,high); } } }
归并排序:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个有序的子序列,再把有序的子序列合并为整体有序序列。
算法如下:
public class MergeSort { public static void main(String[] args) { int a[] = {1,5,3,4,5,8,10,21,4,5,1}; int b[] = new int[a.length]; mergeSort(a,b,0,a.length-1); for(int i =0;i<b.length;i++){ System.out.print(b[i]+" "); } } //合并 a的low到mid的有序数组,和mid到high的有序数组,合并成b public static void merge(int a[],int b[],int low,int mid,int high){ int i = low,j=mid+1,k=low; while(i<=mid&&j<=high){ if(a[i]<a[j]) b[k++] = a[i++]; else b[k++] = a[j++]; } while(i<=mid){ b[k++] = a[i++]; } while(j<=high){ b[k++] = a[j++]; } } public static void mergeSort(int a[],int b[],int low,int high){ //s是中间数组 int s[] = new int[a.length]; if(low==high) b[low] = a[low]; else{ int mid = (low+high)/2; mergeSort(a,s,low,mid); mergeSort(a,s,mid+1,high); merge(s,b,low,mid,high); } } }
本文章是我这两天看过总结的java代码,有些话说的太白了,可能不易于理解,请大家见谅。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。