Java数据结构--排序
2016-04-27 15:37
375 查看
最近实验室的技术沙龙开展起来了,我想着讲点基础的,讲讲最基本的排序算法吧。相比于画图讲思想,我更喜欢实现了的代码,所以我就根据代码写一下。(代码默认升序排列)
插入排序:
冒泡排序:
快速排序:(由于比较重要,解释的清楚些)
快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。
举例说明一下吧,这个可能不是太好理解。假设要排序的序列为
2 2 4 9 3 6 7 1 5 首先用2当作基准,使用i j两个指针分别从两边进行扫描,把比2小的元素和比2大的元素分开。首先比较2和5,5比2大,j左移
2 2 4 9 3 6 7 1 5 比较2和1,1小于2,所以把1放在2的位置
2 1 4 9 3 6 7 1 5 比较2和4,4大于2,因此将4移动到后面
2 1 4 9 3 6 7 4 5 比较2和7,2和6,2和3,2和9,全部大于2,满足条件,因此不变
经过第一轮的快速排序,元素变为下面的样子
[1] 2 [4 9 3 6 7 5]
之后,在把2左边的元素进行快排,由于只有一个元素,因此快排结束。右边进行快排,递归进行,最终生成最后的结果。
选择排序:
归并排序:
下面是每种算法的时间复杂度和空间复杂度:
插入排序:
//插入排序 public static void InsertSort(int[] num){ if (num.length<=0) { //判断数组是否为空 return; } //插入排序的思想是:将选取的元素插入到有序序列,依次插入,直到所有元素有序 for (int i = 1; i < num.length; i++) { int tmp = num[i]; int j=i-1; while(num[j]>tmp){ num[j+1]=num[j]; //如果比tmp大,则后移 j--; if (j<0) { break; } } num[j+1]=tmp; //直到找到一个比tmp小或者到了起始点,将其插入 } }
冒泡排序:
//冒泡排序 public static void BubbleSort(int[] num) { if(num.length<=0) return; //冒泡排序的思想在于取其中一个元素与相邻元素比较,较大者上浮,直到最大的浮到底部 boolean change = true; //此变量为优化算法的比较次数,当有一趟所有元素都未发生交换说明已有序 for (int i = 0; i < num.length&&change; i++) { change = false; for (int j = 0; j < num.length-i-1; j++) { if(num[j]>num[j+1]){ int tmp = num[j]; num[j] = num[j+1]; num[j+1] = tmp; change = true; } } } }
快速排序:(由于比较重要,解释的清楚些)
快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。
举例说明一下吧,这个可能不是太好理解。假设要排序的序列为
2 2 4 9 3 6 7 1 5 首先用2当作基准,使用i j两个指针分别从两边进行扫描,把比2小的元素和比2大的元素分开。首先比较2和5,5比2大,j左移
2 2 4 9 3 6 7 1 5 比较2和1,1小于2,所以把1放在2的位置
2 1 4 9 3 6 7 1 5 比较2和4,4大于2,因此将4移动到后面
2 1 4 9 3 6 7 4 5 比较2和7,2和6,2和3,2和9,全部大于2,满足条件,因此不变
经过第一轮的快速排序,元素变为下面的样子
[1] 2 [4 9 3 6 7 5]
之后,在把2左边的元素进行快排,由于只有一个元素,因此快排结束。右边进行快排,递归进行,最终生成最后的结果。
//快速排序 public static void QuickSort(int[] num,int left,int right) { if(num.length<=0) return; //快拍是一种分治思想的排序,每次选取一个元素p,把序列分为两个部分,比p小的和比p大的,然后迭代 //直到有序为止 if(left<right) { int p = num[left]; int low,high; low = left; high = right; while (low<high) { while (low<high&&num[high]>p) { high--; } num[low] = num[high]; while (low<high&&num[low]<p) { low++; } num[high] = num[low]; } num[low] = p; QuickSort(num, left, low-1); QuickSort(num, low+1, right); } }
选择排序:
//选择排序 public static void SelectSort(int[] num) { if(num.length<=0) return; //选择排序是选取一个临时变量来记录每一躺的最大值,然后放在序列的尾端 for(int i =0;i<num.length;i++){ int x=num[i]; int y=i; int j; for (j = i; j < num.length; j++) { if(num[j]<x){ x=num[j]; y=j; } } num[y]=num[i]; num[i]=x; } }
归并排序:
//归并排序 public static void MergeArray(int[] num,int left,int mid,int right) { int i=left,j=mid+1,k=0; int[] tmp = new int[right-left+1]; while (i<=mid&&j<=right) { if (num[i]>num[j]) { tmp[k++] = num[j++]; } else { tmp[k++] = num[i++]; } } while (i<=mid) { tmp[k++] = num[i++]; } while (j<=right) { tmp[k++] = num[j++]; } int m=0; for (int l = left; l < right+1; l++) { num[l] = tmp[m++]; } } public static void MergeSort(int[] num,int left,int right) { //归并排序的思想是将序列划分成两段,然后用递归,直到序列只有两个元素,然后将有序的序列进行合并 if(left<right){ int mid = (left+right)/2; MergeSort(num, left, mid); MergeSort(num, mid+1, right); MergeArray(num, left, mid, right); } }
下面是每种算法的时间复杂度和空间复杂度:
相关文章推荐
- 数据结构中哈夫曼树水题代码
- 直接插入排序
- HashMap的元素hash散列均匀必要性及算法优化
- C/C++数据结构
- 【数据结构】【面试题】找N个数据中最大的K个数据
- 【数据结构】用模版实现大小堆、实现优先级队列,以及堆排序
- 【数据结构】将一组数据升序排序(利用堆排序)
- 数据结构--优先级队列
- 数据结构和算法 c#– 1.单项链表
- 字符串匹配KMP算法
- 数据结构与算法——图的邻接表表示法类的C++实现
- 算法与数据结构(二) 基于链表的队列
- 数据结构与算法习题汇总(4)
- 数据结构 - 栈的顺序实现
- 数据结构之链表学习笔记
- 【数据结构】找出N个数据中最大的前k个数据(利用堆排序)
- 数据结构与算法笔记 —— 查找算法及代码实现
- 数据结构之链表的增删操作的Java实现
- 数据结构之排序算法实现(选自大话数据结构)
- 数据结构-堆排序