基础数据结构与算法实现(1)—排序算法

一.选择排序

public class Selection {
        
        public static void sort(int[] a) {
                //将a[]按升序排列
                int N=a.length;
                for(int i=0;i<N;i++) {
                        int min=i; //最小值对应索引
                        for(int j=i+1;j<N;j++) {
                                if(a[j]<a[min])
                                        min = j;
                        }
                        exch(a,i,min);
                }         
        }
        
        //交换
        private static void exch(int[] a,int i,int j) {
                int t = a[i];
                a[i]=a[j];
                a[j]=t;
        }
       
        //测试用例
        public static void main(String[] args) {
                int[] arr= {9,8,7,6,5,4,3,2,1};
                sort(arr);
                for(int i=0;i<arr.length;i++) {
                        System.out.print(arr[i]);
                }
        }
       
}

二.插入排序及其一种改进(无需交换)


public class Insertion{
        
        //交换 每次循环都访问数组2次
        public static void exchSort(int[] a) {
                
                int N=a.length;
                
                for(int i=1;i<N;i++) {
                        for(int j=i;j > 0 && a[j]<a[j-1];j--) {
                                exch(a,j,j-1);
                        }
                }

        }
        
        //不需交换 每次循环都访问数组1次
        public static void noexchSort(int[] a) {
                
                int N = a.length;
                
                for(int i=1;i<N;i++) {
                        int t=a[i];
                        int j;
                        for(j=i-1;j>=0 && t<a[j];j--) {
                                a[j+1] = a[j];//较大的元素右移
                        }
                        a[j+1] = t; //插入i位置的值
                }
                
        }
        
        

        //交换
        private static void exch(int[] a,int i,int j) {
                int t = a[i];
                a[i]=a[j];
                a[j]=t;
        }
        
        public static void main(String[] args) {
                int[] arr1= {9,8,7,6,5,4,3,2,1};
                int[] arr2= {9,8,7,6,5,4,3,2,1};
                
                //运行时间7824nm
                long startTime = System.nanoTime();
                //测试使用交换的插入排序
                exchSort(arr1);
                long endTime = System.nanoTime();
                System.out.println("exchSort程序运行时间: "+(endTime-startTime));
                
                //运行时间4969nm
                long startTime2 = System.nanoTime();
                //测试没有使用交换的插入排序
                noexchSort(arr2);
                long endTime2 = System.nanoTime();
                System.out.println("noexchSort程序运行时间: "+(endTime2-startTime2));

        }
        

}

三.希尔排序

        public static void shell(int[] a) {
                
                int N=a.length;
                int h=1;
                
                while(h<N/2) {
                        h = 2*h+1;
                }
                
                while(h >= 1) {
                        for(int i=h;i<N;i++) {
                                for(int j=i;j>=h && a[j]<a[j-h];j -=h)
                                        exch(a,j,j-h);
                        }
                        h=h/2;
                }
                
                     
        }

四.归并排序-自顶向下

import java.util.Arrays;

public class Merge{
        
        public static void main(String []args){
                int []arr = {8,4,5,7,1,3,6,2,9};
                sort(arr);
                System.out.println(Arrays.toString(arr));
        }
        
        public static void sort(int[] arr) {
                int[] temp=new int[arr.length];
                sort(arr,0,arr.length-1,temp);
        }
        
        private static void sort(int[] arr,int left,int right,int[] temp) {
                if(left<right) {
                        int mid = (left+right)/2;
                        sort(arr,left,mid,temp); //左边归并排序,使得左子序列有序
                        sort(arr,mid+1,right,temp); //右边归并排序,使得右子序列有序
                        merge(arr,left,mid,right,temp); //将两个有序子数组合并
                }
        }
        
        private static void merge(int[] arr,int left,int mid,int right,int[] temp) {
                
                int i = left; //左序列指针
                int j = mid+1; //右序列指针
                int t = 0;//临时数组指针
                
                //当左右序列均未到头时
                while (i<=mid && j<=right) {
                        if(arr[i] <= arr[j]){
                                temp[t++]=arr[i++];
                        }else {
                                temp[t++]=arr[j++];
                        }
                }
                
                //右边序列到头,将左边剩余元素填充temp
                while(i <= mid) {
                        temp[t++] = arr[i++];
                }
                
              //左边序列到头,将右边剩余元素填充temp
                while(j<=right) {
                        temp[t++] = arr[j++];
                }
                
                t=0;
                //将temp中的元素全部拷贝到原数组中
                while(left <= right) {
                        arr[left++] = temp[t++];
                }
               
        }
}

五.归并排序-自底向上

         public static void mergeBU(int[] arr) {
                 int N = arr.length;
                 int[] temp = new int[arr.length];
                 //size表示归并子数组的长度 1表示一个个归并 2表示2个数组归并
                 for(int size=1;size<N;size=2*size) {
                         for(int left=0;left<N-size;left+=2*size) {
                                 System.out.println(Arrays.toString(temp));
                                 merge(arr, left,
                                            left+size-1,
                                            Math.min(left+size+size-1,N-1),temp);
                         }
                 }
         }

六.快速排序

import java.util.Random;
public class QuickSort {
        
        public static void sort(int[] a) {
                sort(a,0,a.length-1);
        }
        
        private static void sort(int[] a,int left,int right) {
                if(right <= left) {
                        return;
                }
                        
                int j = partition(a,left,right);
                sort(a,left,j-1);
                sort(a,j+1,right);
        }
        
        private static int partition(int[] a,int left,int right) {
                
                //随机选取切分点
                Random rand = new Random();
                int randIndex = rand.nextInt(right-left+1)+left;
                
                exch(a,left,randIndex);
                
                int i = left;
                int j = right+1;
                int k = a[left];
                
                while(true) {
                        while(a[++i]<k)
                                if(i==right)
                                        break;
                        while(a[--j]>k)
                                if(j==left)
                                        break;
                        
                        if(i>=j)
                                break;
                        
                        exch(a,i,j);
                       
                    
                }
                
                exch(a,left,j);
                
                return j;
                
                
        }
        
        private static void exch(int[] a,int i,int j) {
                int t = a[i];
                a[i]=a[j];
                a[j]=t;
        }
        
}

七.三向切分的快速排序

public class Quick3way {
        
        public static void sort(int[] a) {
                sort(a,0,a.length-1);
        }
        
        private static void sort(int[] a,int left,int right) {
                
                if(left>=right)
                        return;
                
                int lt = left,i = left+1,gt = right; //定义三个指针
                int v = a[left];
                
                //使得a[left...lt-1]<v=a[lt...gt]<a[gt+1...right]
                while(i<=gt) {
                        if(a[i]<v) {
                                exch(a,lt++,i++);
                        }else if(a[i]>v) {
                                exch(a,i,gt--);
                        }else {
                                i++;
                        }
                }
                
                sort(a,left,lt-1);
                sort(a,gt+1,right);
              
        }
        
        private static void exch(int[] a,int i,int j) {
                int t = a[i];
                a[i]=a[j];
                a[j]=t;
        }
        
}

猜你喜欢

转载自blog.csdn.net/weixin_41993767/article/details/83339719