常见几种排序

二分查找

/// 二分查找
/// @param arr <#arr description#>
/// @param target <#target description#>
/// @param n <#n description#>
int binarySearch(int *arr, int target, int n) {
    int left = 0, right = n - 1;
    
    // 在 [left..right]的范围内寻找target, 当left = right 时, 区间[left...right]依然是有效的
    while (left <= right) {
        //left和right比较大的话, 相加会造成整型溢出
//        int pivot = (left + right)/2;
        int pivot = left + (right - left)/2;

        if (arr[pivot] == target) return pivot;
        if (arr[pivot] < target) left = pivot + 1;
        else right = pivot - 1;
    }
    
    return -1;
}
View Code

 

冒泡排序: 

struct Array {
    int * pBase;
    int length;
    int current;
};

void sort_array(struct Array * pArray) {
    
    int i, j, t;
    
    for (i = 0; i < pArray->current; i++) {
        
        for (j = i+1; j < pArray->current; j++) {
            
            if (pArray->pBase[i] > pArray->pBase[j]) {
                t = pArray->pBase[i];
                pArray->pBase[i] = pArray->pBase[j];
                pArray->pBase[j] = t;
            }
        }
    }
    
}
View Code

 

快速排序

///  快速排序
/// @param array 要排序的数组
/// @param L 数组第0个索引
/// @param R 数组最后一个索引
void quickSort(int array[], int L, int R) {

    //左侧索引大于右侧索引时直接返回
    if (L > R) return;
    
    int i = L, j = R, pivot = array[L], temp;
    
    //双轴左右索引没有相遇之前, 一直循环移动左右索引遍历
    while (L != R) {
        
        //右侧索引在没有找到比pivot小的值之前, 一直向左移动, 一直到找到小于pivot的值后, 停下
        while (array[j] >= pivot && i < j ) {
            j --;
        }
        
        //左侧索引在没有找到比pivot大的值之前, 一直向右移动, 一直到找到大于pivot的值后, 停下
        while (array[i] <= pivot && i < j) {
            i++;
        }
        
        //右侧找到比pivot小的值后, 左侧找到比pivot大的值后, 将数组索引为i和j的值进行交换, 同时在左右没有相遇之前保证i小于j
        if (i < j) {
            temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }

    }
    
    //左右相遇, i就是pivot的位置, 交换L和i的位置
    array[L] = array[i];
    array[i] = pivot;
    
    //找到pivot的位置后, 然后在pivot左右两侧分别进行快排
    quickSort(array, L, i-1);
    quickSort(array, i+1, R);
}
View Code

 

 插入排序

/// 插入排序
/// 从素引 i 为1的位置开始, j 往左侧走, 依次和 i 前面的数比较, 如果第j个值小于第j-1个值, 两两交换, 然后一直循环到 j=1的位置
/// 然后再从i 为2的位置开始, 重复上述步骤, 直至数组最后一个元素
/// @param array 要排序的数组
void insertionSort(int array[]) {
    
    int i, j, temp;
    
    for (i=1; i < sizeof(&array); i++) {
        
        for (j=i; j > 0 && array[j] < array[j-1]; j--) {
            
            temp = array[j];
            array[j] = array[j-1];
            array[j-1] = temp;
            
        }
    }
}
View Code

  

选择排序

/// 选择排序
/// @param arr 数组
/// @param n 数组长度
void selectionSort(int arr[], int n) {
    int min = 0, tem = 0;
    for (int i=0; i<n; i++) {
        
        min = i;
        
        for (int j=i+1; j<n; j++) {
            if (arr[j] < arr[min]) {
                min = j;
            }
        }
        
        if (min != i) {
            tem = arr[min];
            arr[min] = arr[i];
            arr[i] = tem;
        }
        
    }
}
View Code

 

归并排序

/// 归并排序
/// @param arr <#arr description#>
/// @param L <#L description#>
/// @param R <#R description#>
void mergeSort(int arr[], int L, int R) {

    if (L == R) {
        return;
    }else{
        int M = (L+R)/2 + 1;

        mergeSort(arr, L, M - 1);

        mergeSort(arr, M , R);

        merge(arr, L, M, R);

    }

}
View Code

 

堆排序

/// 时间复杂度为O(nlogn )
/// 将父节点值和子节点进行比较, 然后将最大值和父节点值进行交换
/// 堆: 满二叉树 && 父节点的值大于子节点
///  i 节点的父节点:  parent = (i - 1) / 2
///  i 节点的左节点: c1 = 2 * i + 1
///  i 节点的右节点:  c2  = 2 * i +  2
///  要对第i个节点进行heapify, 先找到第i个节点的两个子节点, 然后进行值比较, 交换
/// @param tree 满二叉树(数组表示 , 从上往下, 从左往右)
/// @param n 数组的节点
/// @param i 要对哪个节点进行heapify ( 堆化 )
void heapify(int tree[], int n, int i) {
    if (i >= n) return;
    
    int c1 = 2 * i + 1;
    int c2 = 2 * i + 2;
    int max = i;
    
    if (c1 < n && tree[c1] > tree[max]) {
        max = c1;
    }
    
    if (c2 < n && tree[c2] > tree[max]) {
        max = c2;
    }
    
    if (max != i) {
        int temp = tree[max];
        tree[max] = tree[i];
        tree[i] = temp;
    }
    
}


/// 交换数组的两个值
/// @param tree <#tree description#>
/// @param i <#i description#>
/// @param j <#j description#>
void swap(int tree[], int i, int j) {
    int temp = tree[i];
    tree[i] = tree[j];
    tree[j] = temp;
}

/// 构建堆
/// @param tree 表示树的数组
/// @param n 数组的个数
void build_heap(int tree[], int n) {
    int last_node = n - 1;
    int parent = (last_node - 1) / 2;
    int i;
    for (i = parent; i >= 0; i--) {
        heapify(tree, n, i);
    }
}


/// 堆排序
/// @param tree 表示树的数组
/// @param n 数组的个数
void heap_sort(int tree[], int n) {
    build_heap(tree, n);
    int i;
    for (i = n - 1; i > 0; i--) {
        swap(tree, i, 0);
        heapify(tree, i, 0);
    }
    
    
}
View Code

 

合并两个已经排好序的数组

//合并两个已经排好序的数组
void merge(int array[], int L, int M, int R) {

    int LEFT_SIZE = M - L;
    int RIGHT_SIZE = R - M + 1;
    int left[LEFT_SIZE];
    int right[RIGHT_SIZE];

    //左边数组填充数据
    for (int i=L; i<M; i++) {

        left[i-L] = array[i];
    }

    //右边数组填充数据
    for (int i=M; i<=R; i++) {

        right[i-M] = array[i];
    }


    int i = 0, j = 0, k = L;

    //分别从左右两个数组比较数据, 填充到整个数组中
    while (i < LEFT_SIZE && j < RIGHT_SIZE) {

        if (left[i] < right[j]) {
            array[k] = left[i];
            i++;
            k++;
        }else {
            array[k] = right[j];
            j++;
            k++;
        }
    }

    //如果右边数组已经循环完毕, 将左边数组的数据依次填充到数组中
    while (i < LEFT_SIZE) {
        array[k] = left[i];
        i++;
        k++;
    }
    //如果做边数组已经循环完毕, 将右边数组的数据依次填充到数组中
    while (j < RIGHT_SIZE) {
        array[k] = right[j];
        j++;
        k++;
    }
}
View Code

 

posted on 2019-04-25 14:00  JieFangZhe  阅读(113)  评论(0编辑  收藏  举报

导航