数据结构之排序算法——汇总

来源:互联网 发布:济南整站优化方案 编辑:程序博客网 时间:2024/06/05 08:51

排序算法应该是最基础的算法了,博主面试至今没有面试官单就一个排序算法让写个代码什么的。本篇小博先对常见的排序算法进行一下总结,方便日后查看吧。主要内容包括:冒泡排序(快速排序)、选择排序(堆排序)、插入排序(希尔排序)、归并排序。

一、冒泡排序

代码如下:

public static int[] BubbleSort(int[] a) {if(a == null || a.length < 2)return a;for(int i = 0; i < a.length-1; i++) {int  flag = 0;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;flag = 1;}}if(flag == 0)break;}return a;}

二、选择排序

思路:两个循环变量i和j,一个最小值指针min,外层循环从0开始,min每次都初始化为i,内层循环j从i+1开始,其性能略优于冒泡排序法,代码如下:

public static int[] SelectSort(int[] a) {if(a == null || a.length < 2)return a;for(int i = 0; i < a.length-1; i++) {int min = i;boolean change = false;for(int j = i+1; j < a.length; j++) {if(a[j] < a[min]) {min = j;change = true;}}if(change) { //a[i]恰好就是当前序列中最小的那个int temp = a[i];a[i] = a[min];a[min] = temp;}}return a;}
三、插入排序

思路:遍历数组,将数组后面的数按照顺序插入到正确的位置,代码如下

public static int[] InsertSort(int[] a) {if(a == null || a.length < 2)return a;for(int i = 1; i < a.length; i++) {int j = i;while(j > 0 && a[j] < a[j-1]) {int temp = a[j];a[j] = a[j-1];a[j-1] = temp;j--;}}return a;}
四、希尔排序

思路:分组的插入排序,代码如下:

public static int[] ShellSort(int[] a) {<span style="white-space:pre"></span>if(a == null || a.length < 2)<span style="white-space:pre"></span>return a;<span style="white-space:pre"></span>for(int increment = a.length/3; increment > 0; increment /= 3) { //确定增量<span style="white-space:pre"></span>for(int i = increment; i < a.length; i+=increment) {<span style="white-space:pre"></span>int j = i;<span style="white-space:pre"></span>while(j > 0 && a[j] < a[j-increment]) {<span style="white-space:pre"></span>int temp = a[j];<span style="white-space:pre"></span>a[j] = a[j-increment];<span style="white-space:pre"></span>a[j-increment] = temp;<span style="white-space:pre"></span>j-=increment;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}        return a;<span style="white-space:pre"></span>}

五、堆排序

关键问题:怎么将一个数列变成为一个大顶堆,其实质就是从下往上、从右到左将每个非终端节点当做根节点,将其和其子树调整成大顶堆,代码如下

public static void HeapAdjust(int[] a, int s, int m) {<span style="white-space:pre"></span>int temp = a[s];<span style="white-space:pre"></span>for(int i = 2*s+1; i < m; i = i*2+1) { //2*s+1是左孩子的下标<span style="white-space:pre"></span>if(i < m && a[i] < a[i+1])         //左孩子 < 右孩子<span style="white-space:pre"></span>++i;                           //i就变成了右孩子的下标<span style="white-space:pre"></span>if(temp >= a[i])                   //如果根节点大于孩子节点了 break<span style="white-space:pre"></span>break;<span style="white-space:pre"></span>a[s] = a[i];                       //根节点值变成较大的孩子节点<span style="white-space:pre"></span>s = i;                             //下次循环的根节点变成这次的较大孩子节点<span style="white-space:pre"></span>}<span style="white-space:pre"></span>a[s] = temp;                           //较大孩子节点处的值变成根节点<span style="white-space:pre"></span>} //程序本质就是完成根节点与孩子节点的交换,选出最大值作为新的根节点public static int[] HeapSort(int[] a) {if(a == null || a.length < 2)return a;for(int i = a.length/2; i > 0; i--) {  //先完成堆创建,最大值跑到根节点HeapAdjust(a,i-1,a.length-1);}for(int i = a.length-1; i > 1; i--) {int temp = a[i];a[i] = a[0];a[0] = temp;HeapAdjust(a,0,i-1);}return a;}

六、归并排序

主要用到了合并两个有序数组为一个有序数组,递归调用,代码如下:

public static void merge(int[] nums, int low, int mid, int high) {  int[] temp = new int[high - low + 1];  int i = low;// 左指针  int j = mid + 1;// 右指针  int k = 0;  // 把较小的数先移到新数组中  while (i <= mid && j <= high) {  if (nums[i] < nums[j]) {  temp[k++] = nums[i++];  } else {  temp[k++] = nums[j++];  }  }  // 把左边剩余的数移入数组  其实这两个while只会执行一个,因为短的那个i/j已经 >mid/high了while (i <= mid) {  temp[k++] = nums[i++];  }  // 把右边边剩余的数移入数组  while (j <= high) {  temp[k++] = nums[j++];  }  // 把新数组中的数覆盖nums数组  for (int k2 = 0; k2 < temp.length; k2++) {  nums[k2 + low] = temp[k2];  }  }public static int[] sort(int[] nums,int low,int high) {int mid = (low + high)/2;if(low < high) {sort(nums, low, mid);  sort(nums, mid + 1, high);  merge(nums,low,mid,high);}return nums;}public static int[] MergeSort(int[] a) {if(a == null || a.length < 2) {return a;}return sort(a,0,a.length-1);}

七、快速排序

//基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,    //一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。//快速排序是不稳定的排序。//快速排序的时间复杂度为O(nlogn)。//当n较大时使用快排比较好,当序列基本有序时用快排反而不好。public static int getMiddle(int[] a,int low,int high) { //完成选取基值,左右选边的过程int temp = a[high]; //基值的位置while(low < high) {while(low < high && a[high] > temp) {high--;}while(low < high && a[low] < temp) {low++;}int t = a[low];a[low] = a[high];a[high] = t;}return high;}public static void qsort(int[] a,int low,int high) {if(low < high) {int mid = getMiddle(a,low,high);qsort(a,low,mid-1);qsort(a,mid+1,high);}}public static void quickSort(int[] a,int low,int high) {if(a.length > 0) {qsort(a,0,a.length-1);}}}





0 0
原创粉丝点击