• 归并排序和选择排序:Java 和c实现


    1.归并排序与选择排序

    归并排序定义:归并排序就是将两个或两个以上的有序表合并成一个有序表的过程。将两个有序表合并成一个有序表的过程称为2-路归并。

    选择排序定义:每一趟从待排序的记录中选出关键字最小的记录,按顺序放在已排序的记录序列的最后,直到全部排完为止。

    注意:1.选择是把一个文件分成包含k个最小元素和n-k个最大元素的两个部分的过程。

    2.选择和归并互为逆操作:选择是把一个序列分成两部分,归并把两个文件合并成一个文件

    3.归并排序是快速排序的补充

    4.归并排序以连续的方式访问数据

    5.归并排序适用于链表排序。

    6.归并排序对输入的初始次序不敏感。

    2.归并排序全过程

    4 9 15 24 30

    (画图功力不行,还是贴图吧,,,,)

    此时,比较结束后,把A中左项或子项剩余的元素整体复制到B中去,排序完成。

    排序算法如下:

    
    void Merge(SqList L,int low,int m,int high)
    {
    	
    	int B[high-low+1];
    	int i=low,j=m+1,k=0;
    	while(i<=mid&&j<=high)
    	{
    		B[k++]=L.elem[i]<=L.elem[j]?L.elem[i++]:L.elem[j++];
    	}
    	while(i<=mid) B[k++]=L.elem[i++];
    	while(j<=high) B[k++]=L.elem[j++];
    	for(i=low,k=0;i<=high;i++)
    	{
    		L.elem[i]=B[k++];
    	}
    	delete []B;
    	} 

    当然这个算法的前提是两个排好序的表合并成一个表,那么如何解决一个乱序表的排序问题呢,其实可以利用递归思想,即把一个乱序表分成两个子序表,再把子序表各自分出两个子子序表,,,直到分到序列表长度为1为止,此时两两进行排序,不断的向回排序。

    递归算法:

    void MergeSort(SqList L,int low,int high)  
    {     
        /*用分治法进行二路归并排序*/  
        int mid;  
        if(low<high)  /*区间长度大于1*/
        {      
            mid=(low+high)/2;               /*分解*/
            MergeSort(L,low,mid);           /*递归地对low到mid序列排序 */ 
            MergeSort(L,mid+1,high);        /*递归地对mid+1到high序列排序 */ 
            Merge(L,low,mid,high);          /*归并*/  
        }  
    }
    

    3.

    归并排序分析:

    归并排序将输入序列分成两部分并递归地处理每一部分。当子问题解决后,算法又将子问题地解合并。假设具有n个元素地归并排序地复杂度表示为T(n),则归并排序的递归式可定义为:

    T(n)=2T(n/2)+O(n);

    根据分治法主定理:T(n)=O(nlogn)

    4.性能

    最坏情况下时间复杂度:O(nlogn)

    最好情况下时间复杂度:O(nlogn)

    平均情况下时间复杂度:O(nlogn)

    最坏情况下空间复杂度:O(n)辅助

    选择排序:

    选择排序是一种原地排序算法,适用于小文件,由于选择操作是基于键值的且交换操作只在需要时才执行,所以选择排序常用于数值较大和键值较小的文件。

    优点:容易实现,原地排序不需要额外的存储空间

    缺点:扩展性较差:O(n^2)

    算法:

    1.寻找序列中的最小值。

    2.用当前位置的值交换最小值。

    3.对于所有元素重复上述过程,直到整个序列排序完成。

    void Selection(int A[],int n)
        int i,j,min,temp;
    for(i=0;i<n-1;i++)
        {
            min=i;
            for(j=i+1;j<n;j++)    
                {
                    if(A[j]<A[min])
                        {
                            min=j;
                        }
               temp=A[min];
                A[min]=A[i];
                A[i]=temp;
                }
           }
    

    最坏情况时间复杂度:O(n^2)

    最好情况时间复杂度:O(n)

    最坏情况下空间复杂度:O(1)

    附归并排序Java代码

    package cn.sal.paixu;
    
    import java.util.Arrays;
    
    public class MergeSort {
    
    	public static void mergeSort(int[] arr) {
    		if (arr == null || arr.length < 2) {
    			return;
    		}
    		mergeSort(arr, 0, arr.length - 1);
    	}
    
    	public static void mergeSort(int[] arr, int l, int r) {
    		if (l == r) {
    			return;
    		}
    		int mid = l + ((r - l) >> 1);
    		mergeSort(arr, l, mid);
    		mergeSort(arr, mid + 1, r);
    		merge(arr, l, mid, r);
    	}
    
    	public static void merge(int[] arr, int l, int m, int r) {
    		int[] help = new int[r - l + 1];
    		int i = 0;
    		int p1 = l;
    		int p2 = m + 1;
    		while (p1 <= m && p2 <= r) {
    			help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
    		}
    		while (p1 <= m) {
    			help[i++] = arr[p1++];
    		}
    		while (p2 <= r) {
    			help[i++] = arr[p2++];
    		}
    		for (i = 0; i < help.length; i++) {
    			arr[l + i] = help[i];
    		}
    	}
    
    	// for test
    	public static void comparator(int[] arr) {
    		Arrays.sort(arr);
    	}
    
    	// for test
    	public static int[] generateRandomArray(int maxSize, int maxValue) {
    		int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
    		for (int i = 0; i < arr.length; i++) {
    			arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
    		}
    		return arr;
    	}
    
    	// for test
    	public static int[] copyArray(int[] arr) {
    		if (arr == null) {
    			return null;
    		}
    		int[] res = new int[arr.length];
    		for (int i = 0; i < arr.length; i++) {
    			res[i] = arr[i];
    		}
    		return res;
    	}
    
    	// for test
    	public static boolean isEqual(int[] arr1, int[] arr2) {
    		if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
    			return false;
    		}
    		if (arr1 == null && arr2 == null) {
    			return true;
    		}
    		if (arr1.length != arr2.length) {
    			return false;
    		}
    		for (int i = 0; i < arr1.length; i++) {
    			if (arr1[i] != arr2[i]) {
    				return false;
    			}
    		}
    		return true;
    	}
    
    	// for test
    	public static void printArray(int[] arr) {
    		if (arr == null) {
    			return;
    		}
    		for (int i = 0; i < arr.length; i++) {
    			System.out.print(arr[i] + " ");
    		}
    		System.out.println();
    	}
    
    	// for test
    	public static void main(String[] args) {
    		int testTime = 500000;
    		int maxSize = 100;
    		int maxValue = 100;
    		boolean succeed = true;
    		for (int i = 0; i < testTime; i++) {
    			int[] arr1 = generateRandomArray(maxSize, maxValue);
    			int[] arr2 = copyArray(arr1);
    			mergeSort(arr1);
    			comparator(arr2);
    			if (!isEqual(arr1, arr2)) {
    				succeed = false;
    				printArray(arr1);
    				printArray(arr2);
    				break;
    			}
    		}
    		System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    
    		int[] arr = generateRandomArray(maxSize, maxValue);
    		printArray(arr);
    		mergeSort(arr);
    		printArray(arr);
    
    	}
    
    }
    
  • 相关阅读:
    LintCode: Convert Sorted Array to Binary Search Tree With Minimal Height
    LNMP企业应用部署全过程(基于DEDE后台)
    提高Web服务器并发响应的经历
    提高Web服务器并发响应的经历
    提高Web服务器并发响应的经历
    提高Web服务器并发响应的经历
    华为设备RIP实施和理论详解
    华为设备RIP实施和理论详解
    MySQL 官方 Docker 镜像的使用
    Docker之docker设置系统的环境变量
  • 原文地址:https://www.cnblogs.com/chmusk/p/11078923.html
Copyright © 2020-2023  润新知