package sort; /** * @author Administrator * @version 创建时间:2018年4月12日 上午9:32:48 * @ClassName 类名称 * @Description 类描述 */ public class Sort { private int[] nums= {2,4,6,7,98,0,2,6,9,1}; //private int[] nums= {5,4,3,2,1}; public void swap(int[] nums,int i,int j){//交换数组等集合里的元素,引用传递,而非值传递 int temp; temp =nums[i]; nums[i]=nums[j]; nums[j]=temp; } public void BubbleSort0(int[] nums,int n){//冒泡排序初级版:最最简单的交换排序 int i,j; for(i=0;i<n-1;i++){ for(j=i+1;j<n;j++){ if(nums[i]>nums[j]) swap(nums,i,j); } } } public void BubbleSort(int[] nums,int n){//冒泡排序 int i,j; for(i=0;i<n;i++){//每一轮比较把最小的放最前面 for(j=n-1;j>i;j--){//从最后到i两两交换,较小者放在前面,即“冒泡”,注意j是从后往前循环 if(nums[j-1]>nums[j]) swap(nums,j-1,j); } } } /*冒泡排序优化,增加标记来减少排序次数,避免因已经有序的情况下的无意义循环判断。*/ public void BubbleSort2(int[] nums,int n){ int i,j,flag=1;//flag用于标记是否有交换操作 for(i=0;i<n && flag==1;i++){//若flag为0,表示没有发生交换,则退出循环 flag = 0;//0表示没有交换 for(j=n-1;j>i;j--){ if(nums[j-1]>nums[j]){ swap(nums,j-1,j); flag = 1;//若产生交换,flag置为1 } } } } //选择排序:寻找序列中的最小值,用当前位置的值交换最小值 public void SelectSort(int[] nums,int n){ int i,j,min; for(i=0;i<n-1;i++){ min=i; //将当前下标定义为最小值下标 for(j=i+1;j<n;j++){ //循环之后的数据 if(nums[j]<nums[min]){//如果有小于当前最小值的关键字,将此关键字的下标赋值给min min=j; } if(i!=min) //若min不等于i,说明找到最小值,交换 swap(nums,i,min); } } } /* 插入排序 * 基本思想是在遍历数组的过程中,假设在序号 i (i>=1)之前的元素即 [0..i-1] 都已经排好序, * 本趟需要找到 i 对应的元素 x 的正确位置 k ,并且在寻找这个位置 k 的过程中逐个将比较过的元素往后移一位, * 为元素 x “腾位置”,最后将 k 对应的元素值赋为 x */ public void InsertSort(int[] nums,int n){ int i,j,temp; for(i=1;i<n;i++){ //只有当前位置i元素小于已经有序的[0,i-1]中的最大元素nums[i-1]时,才需要进行插入 if(nums[i]<nums[i-1]){ temp=nums[i];//存当前位置i的元素,其中[0,i-1]已经有序 for(j=i;j>0&&nums[j-1]>temp;j--){ nums[j]=nums[j-1];//从i-1开始遍历到0,比temp大的数后移一位 } nums[j]=temp;//插入到合适的位置 } } } /* 希尔排序 */ public void ShellSort(int[] nums,int n){ int i,j,temp; int h = 1; /* 关于步长,取值没有统一标准,必须小于size,最后一次步长要为1 */ for(h = 1;h < n/3;h= 3*h+1);//计算首次步长 for(;h>0;h=h/3){ for(i=h;i<n;i++){ //只有当前位置i元素小于已经有序的[0,i-1]中的最大元素nums[i-h]时,才需要进行插入 if(nums[i]<nums[i-h]){ temp=nums[i];//存当前位置i的元素,其中[0,i-1]已经有序 for(j=i;j>h-1&&nums[j-h]>temp;j=j-h){ nums[j]=nums[j-h];//从i-h开始遍历到h-1,比temp大的数后移h位 } nums[j]=temp;//插入到合适的位置 } } } } /* 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上), * 即[s..m]中记录的关键字除[s]之外均满足堆的定义 ; * s表示所要调整的范围的开始下标,m表示结束的下标, * 即[s,...,m],总个数为m-s+1,m可以取到 */ private void HeapAdjust(int[] nums,int s,int m){ int i,temp; temp = nums[s];//先取出当前元素s for(i=2*s+1;i<=m;i=i*2+1){//从s结点的左子结点开始,也就是2s+1处开始,沿关键字较大的孩子结点向下筛选 if(i<m && nums[i]<nums[i+1]){//i为孩子节点中关键字较大的记录的下标;i<m保证右孩子存在 i++; } if(temp<nums[i]){ //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换) nums[s]=nums[i]; s=i; }else break; } nums[s]=temp;//将当前元素插入到最终的位置 } //堆排序 public void HeapSort(int[] nums,int n){ int i; //1、构建大顶堆 for(i=n/2-1;i>=0;i--){ //从第一个非叶结点从下至上,从右至左调整结构 HeapAdjust(nums,i,n-1);//长度为n,则最后一个元素下标为n-1 } //2.调整堆结构+交换堆顶元素与末尾元素 for(i=n-1;i>=0;i--){ swap(nums,0,i);//将堆顶元素与末尾元素进行交换 HeapAdjust(nums,0,i-1);//重新对堆进行调整 } } //归并排序 public void MergeSort(int[] nums,int n){ int[] temp = new int[n];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间 MSort(nums,temp,0,n-1); } private void MSort(int[] nums,int[] temp,int left,int right){ int mid; //if(left==right) temp[left]=nums[right]; if(left<right){ mid = (left+right)/2; MSort(nums,temp,left,mid);//左边归并排序,使得左子序列有序 MSort(nums,temp,mid+1,right);//右边归并排序,使得右子序列有序 Merge(nums,temp,left,mid,right);//将两个有序子数组合并操作 } } //right为序列最后一位元素下标 private void Merge(int[] nums,int[] temp,int left,int mid,int right){ int i=left; //左序列指针 int j=mid+1; //右序列指针 int k=0; //临时数组指针 while(i<=mid && j<=right){ if(nums[i]<nums[j]){ temp[k++]=nums[i++]; }else{ temp[k++]=nums[j++]; } } while(i<=mid){ //将左边剩余元素填充进temp中 temp[k++]=nums[i++]; } while(j<=right){ //将右序列剩余元素填充进temp中 temp[k++]=nums[j++]; } k = 0; while(left<=right){ //将temp中的元素全部拷贝到原数组中 nums[left++]=temp[k++]; } } //快速排序 public void QuickSort(int[] nums,int n){ QSort(nums,0,n-1); } public void QSort(int[] nums,int low,int high){ int pivot; if(low<high){ pivot=Partition(nums,low,high);/*将L->r[low..high]一分为二,*/ /*算出枢轴值pivot */ QSort(nums,low,pivot-1); QSort(nums,pivot+1,high); } } public int Partition(int[] nums,int low,int high){ int pivotkey=nums[low]; while(low<high){ while(low<high && nums[high]>=pivotkey){ high--; } swap(nums,low,high); while(low<high && nums[low]<=pivotkey){ low++; } swap(nums,low,high); } return low; } //二叉排序树 class Node{//二叉排序树的结点类 public int data; public Node left; public Node right; public Node(int data){ this.data = data; this.left = null; this.right = null; } } private Node root=null; static int ii =0;//指针,将递归中序遍历的有序树放入nums数组中 public void BSTSort(int[] nums,int n){ CreateBST(nums,n);//根据待排序数组生成二叉排序树 MidOrderTraverse(root,nums); } public void InsertNode(int data){ Node newNode = new Node(data); if(root == null){ root = newNode; }else{ Node current = root; Node parent = current; while(current != null){ parent = current; if(data < current.data){ current = current.left; }else{ current = current.right; } } if(data < parent.data){ parent.left = newNode; }else{ parent.right = newNode; } } } public void CreateBST(int[] nums,int n){ for(int i = 0;i<n;i++){ InsertNode(nums[i]); } } //二叉树中序遍历 public void MidOrderTraverse(Node root,int[] nums){ if(root != null){ MidOrderTraverse(root.left,nums); nums[ii++]=root.data; MidOrderTraverse(root.right,nums); } } public static void main(String[] args) { // TODO 自动生成的方法存根 Sort ss = new Sort(); ss.BSTSort(ss.nums, ss.nums.length); for(int i = 0;i<ss.nums.length;i++) System.out.println(ss.nums[i]); } }
各种排序的Java实现
猜你喜欢
转载自blog.csdn.net/ncut_nwpu/article/details/79994288
今日推荐
周排行