• 高等排序_学习笔记


    高等排序_学习笔记

    归并排序

    • 对整个数组进行mergeSort;
    • mergeSort的步骤如下:
      • 将给定的包括n个元素的局部数组“分割”成两个局部数组,每个数组各包括n/2各元素:(devide);
      • 对两个局部数组分别执行mergeSort排序。(solve);
      • 通过merge将两个已排序完毕的局部数组整合成一个数组;

    merge处理是这样的,由于两个待处理的局部数组都完成了排序,因此可以采用复杂度为O(n1+n2)的合并算法:

    #include <iostream>
    using namespace std;
    
    #define MAX 500000
    #define INFTY 200000000000
    
    void merge(int A[], int n, int left, int mid, int right) {
        int n1 = mid-left, n2 = right-mid;
        int L[MAX/2+2], R[MAX/2+2];
        for (int i=0; i<n1; i++) L[i] = A[left+i];
        for (int i=0; i<n2; i++) R[i] = A[mid+i];
        L[n1] = R[n2] = INFTY;
    	int i=0, j=0;
        for (int k=left; k<right; k++) {
            if (L[i]<=R[j]) A[k] = L[i++];
            else A[k] = R[j++];   
        }
    }
    void mergeSort(int A[], int n, int left, int right) {
        if (left+1<right) {
            int mid = (left+right)/2;
            mergeSort(A, n, left, mid);
            mergeSort(A, n, mid, right);
            merge(A, n, left, mid, right);
        }
    }
    
    • 归并排序是稳定排序,复杂度为O(nlongn);

    快速排序

    • 以整个数组为对象执行quickSort;
    • quickSort流程如下:
      • 通过分割将对象局部数组分割为前后两个局部数组;
      • 对前半部分的局部数组执行quickSort;
      • 对后半部分的局部数组执行quickSort;
    int partition(int p, int r) {
        int x, i, j, t;
        x = A[r];
        i = p-1;
        for (j=p; j<r; j++) {
            if (A[j]<=x) {
                i++;
                t = A[i]; A[i] = A[j]; A[j] = t;
            }
        }
        t = A[i+1]; A[i+1] = A[r]; A[r] = t;
        return i+1;
    }
    void quickSort(int A[], int n, int p, int r) {
        int q;
        if (p<r) {
            q = partition(A, n, p, r);
            quickSort(A, n, p, q-1);
            quickSort(A, n, q+1, r);
        }
    }
    
    • 快速排序平均复杂度为O(nlogn),是不稳定排序;

    利用标准库排序

    • 快速排序函数:sort;
    • 归并排序函数:stable_sort;

    实例

    #include <bits/stdc++.h>
    
    using namespace std;
    
    // 打印函数 
    inline void printArr(int A[]) {
    	cout<<"printArr:"<<endl;
    	for (int i=0; i<5; i++) cout<<A[i]<<endl;	
    }
    
    // 归并排序 需要L 和R作为辅助内存 
    #define INFTY 10000
    int L[100], R[100];
    void merge(int A[], int left, int mid, int right) {
    	int n1 = mid-left, n2 = right-mid;
    	// 将左边的数字放到L中,右边的放到R中 
    	for (int i=0; i<n1; i++) L[i] = A[left+i];
    	for (int i=0; i<n2; i++) R[i] = A[mid+i];
    	// 设置一个最大数,避免越界访问 
    	L[n1] = R[n2] = INFTY;
    	int i=0, j=0;
    	// 将L和R中的较小数放进A中实现重排 
    	for (int k=left; k<right; k++) {
    		if (L[i] <= R[j]) A[k] = L[i++];
    		else A[k] = R[j++];
    	}
    }
    
    void mergeSort(int A[], int len, int left, int right) {
    	if (left+1 < right) {
    		int mid = (left+right)/2;
    		mergeSort(A, len, left, mid);
    		mergeSort(A, len, mid, right);
    		merge(A, left, mid, right);
    	}
    }
    
    
    // 快速排序 
    int partition(int A[], int from, int to) {
    	// 将最后一个数字作为val 
    	int val = A[to], tmp;
    	int pos = from-1;
    	// 将小于val的放到左边, 
    	for (int i=from; i<to; i++) {
    		if (A[i] <= val) {
    			++pos;
    			tmp = A[i]; A[i] = A[pos]; A[pos] = tmp; 
    			printArr(A);
    		}
    	}
    	// 将val放到中间,这样小于val就在左边,大于val就在右边 
    	tmp = A[pos+1]; A[pos+1] = A[to]; A[to] = tmp;
    	return pos+1;
    }
    
    
    void quickSort(int A[], int len, int begin, int end) {
    	int mid = 0;
    	if (begin < end) {
    		mid = partition(A, begin, end);
    		// mid位置的数字已经是正确的排序了,因此不用处理他 
    		quickSort(A, len, begin, mid-1);
    		quickSort(A, len, mid+1, end);
    	}
    }
    
    
    
    int main(void) {
    	int A[] = {5,4,3,2,1};
    
    	// 这里实现的快速排序,处理的范围是from-to;
    	// 既包括from也包括to,因此to就是数组最后一位的下标 
    	quickSort(A, 5, 0, 4);
    	
    	// 这里实现的归并排序,处理的范围是left-right;
    	// 包括left但不包括right,因此right是数组最后一位+1 
    	mergeSort(A, 5, 0, 5);
    
    	
    	
    	return 0;
    } 
    
  • 相关阅读:
    第二阶段团队项目冲刺第三天
    第二阶段团队项目冲刺第二天
    第二阶段团队项目冲刺第一天
    第二次冲刺站立会议05
    第二次冲刺站立会议04
    第二次冲刺站立会议03
    第二次冲刺站立会议02
    第二次冲刺站立会议01
    第二次冲刺计划会议
    cnblogs.com的用户体验
  • 原文地址:https://www.cnblogs.com/sakurapiggy/p/13387964.html
Copyright © 2020-2023  润新知