C++编写的常见排序代码

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-30 12:55   36   0

堆排序:

void HeapAdjust(int *array, int parent, int length){
    int temp = array[parent]; // temp保存当前父节点
    int child = 2 * parent + 1; // 先获得左孩子
    while (child < length) {
        // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点
        if (child + 1 < length && array[child] < array[child + 1]) {
            child++;
        }
        // 如果父结点的值已经大于孩子结点的值,则直接结束
        if (temp >= array[child])
            break;
        // 把孩子结点的值赋给父结点
        array[parent] = array[child];
        // 选取孩子结点的左孩子结点,继续向下筛选
        parent = child;
        child = 2 * child + 1;
    }
    array[parent] = temp;
}
void heapSort(int list[], int length) {
    // 循环建立初始堆
    for (int i = length / 2; i >= 0; i--) {
        HeapAdjust(list, i, length);
    }

    // 进行n-1次循环,完成排序
    for (int i = length - 1; i > 0; i--) {
        // 最后一个元素和第一元素进行交换
        int temp = list[i];
        list[i] = list[0];
        list[0] = temp;
        // 筛选 R[0] 结点,得到i-1个结点的堆
        HeapAdjust(list, 0, i);
    }

}

希尔排序:

void shell_sort(int a[], int n)
{
    int d, i, j, temp; //d为增量
    for(d = n/2;d >= 1;d = d/2) //增量递减到1使完成排序
    {
        for(i = d; i < n;i++)   //插入排序的一轮
        {
            temp = a[i];
            for(j = i - d;(j >= 0) && (a[j] > temp);j = j-d)
            {
                a[j + d] = a[j];
            }
            a[j + d] = temp;
        }
    }
}

快排:

int division(int list[], int left, int right) {
    // 以最左边的数(left)为基准
    int base = list[left];
    while (left < right) {
        // 从序列右端开始,向左遍历,直到找到小于base的数
        while (left < right && list[right] >= base)
            right--;
        // 找到了比base小的元素,将这个元素放到最左边的位置
        list[left] = list[right];

        // 从序列左端开始,向右遍历,直到找到大于base的数
        while (left < right && list[left] <= base)
            left++;
        // 找到了比base大的元素,将这个元素放到最右边的位置
        list[right] = list[left];
    }

    // 最后将base放到left位置。此时,left位置的左侧数值应该都比left小;
    // 而left位置的右侧数值应该都比left大。
    list[left] = base;
    return left;
}

void quickSort(int *list, int left, int right) {
    // 左下标一定小于右下标,否则就越界了
    if (left < right) {
        // 对数组进行分割,取出下次分割的基准标号
        int base = division(list, left, right);
        // 对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序
        quickSort(list, left, base - 1);

        // 对“基准标号“右侧的一组数值进行递归的切割,以至于将这些数值完整的排序
        quickSort(list, base + 1, right);
    }
}

计数排序:

void findArrMaxMin(int a[], int size, int *min, int *max)
{
    if(size == 0) {
        return;
    }
    if(size == 1) {
        *min = *max = a[0];
        return;
    }

    *min = a[0] > a[1] ? a[1] : a[0];
    *max = a[0] <= a[1] ? a[1] : a[0];


    int i, j;
    for(i = 2, j = 3; i < size, j < size; i += 2, j += 2) {
        int tempmax = a[i] >= a[j] ? a[i] : a[j];
        int tempmin = a[i] < a[j] ? a[i] : a[j];

        if(tempmax > *max)
            *max = tempmax;
        if(tempmin < *min)
            *min = tempmin;
    }

    //如果数组元素是奇数个,那么最后一个元素在分组的过程中没有包含其中,
    //这里单独比较
    if(size % 2 != 0) {
        if(a[size -1] > *max)
            *max = a[size - 1];
        else if(a[size -1] < *min)
            *min = a[size -1];
    }
}

void count_sort(int a[], int b[], int n) {
    int max, min;
    findArrMaxMin(a, n, &min, &max);
    int numRange = max-min+1;
    int* counter = new int[numRange];

    int i, j, k;
    for (k=0; k<numRange; k++)
        counter[k]=0;

    for (i=0; i<n; i++)
        counter[a[i]-min]++;

    for (k=1; k<numRange; k++)
        counter[k] += counter[k-1];

    for (j=n-1; j>=0; j--) {
        int v = a[j];
        int index = counter[v-min]-1;
        b[index]=v;
        counter[v-min]--;
    }
}

桶排序:

int getNumInPos(int num,int pos) //获得某个数字的第pos位的值
{
    int temp = 1;
    for (int i = 0; i < pos - 1; i++)
        temp *= 10;

    return (num / temp) % 10;
}

#define RADIX_10 10    //十个桶,表示每一位的十个数字
#define KEYNUM 5     //整数位数
void radix_sort(int* pDataArray, int iDataNum)
{
    int *radixArrays[RADIX_10];    //分别为0~9的序列空间
    for (int i = 0; i < RADIX_10; i++)
    {
        radixArrays[i] = new int[iDataNum];
        radixArrays[i][0] = 0;    //index为0处记录这组数据的个数
    }

    for (int pos = 1; pos <= KEYNUM; pos++)    //从个位开始到31位
    {
        for (int i = 0; i < iDataNum; i++)    //分配过程
        {
            int num = getNumInPos(pDataArray[i], pos);
            int index = ++radixArrays[num][0];
            radixArrays[num][index] = pDataArray[i];
        }

        for (int i = 0, j =0; i < RADIX_10; i++) //写回到原数组中,复位radixArrays
        {
            for (int k = 1; k <= radixArrays[i][0]; k++)
                pDataArray[j++] = radixArrays[i][k];
            radixArrays[i][0] = 0;
        }
    }
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP