冒泡排序,选择排序,希尔排序,堆排序,快排,归并排序,计数排序

//冒泡排序
void BubbleSort(int* a, int n)
{
    for (int j = 0; j < n - 1; j++) 
    {
        for (int i = 0; i < n - j - 1; i++)
        {
            if (a[i] > a[i + 1])
            {
                swap(&a[i], &a[i + 1]);
            }
        }
    }
}

// 插入排序
void InsertSort(int* a,int n)
{
    for (int i = 0; i < n - 1; i++)
    {
        int end=i;
        int tem = a[end + 1];
        while (end >= 0)
        {
            if (tem < a[end])
            {
                a[end + 1] = a[end];
                end--;
            }
            else
            {
                break;
            }
            a[end + 1] = tem;
        }
    }
}
// 希尔排序
void ShellSort(int* a, int n)
{
    int gap = n;
    while (gap > 1)
    {
        gap /= 2;
        for (int i = 0; i < n - gap; i++)
        {
            int end = i;
            int tem = a[end + gap];
            while (end >= 0)
            {
                if (tem < a[end])
                {
                    a[end + gap] = a[end];
                    end -= gap;
                }
                else
                {
                    break;
                }
                a[end + gap] = tem;
            }
            print(a, n);
            printf("\n");
        }
    }
}

//堆排序
void AdjustDwon(int* a, int n, int root)
{
    int parent = root;
    int child = parent * 2 + 1;
    while (child < n)
    {
        if (/*child + 1 < n &&*/ a[child] < a[child + 1])
        {
            child++;
        }
        if (a[child] > a[parent])
        {
            swap(&a[child], &a[parent]);
            parent = child;
            child = parent * 2 + 1;
        }
        else
        {
            break;
        }
    }
}
void HeapSort(int* a, int n)
{
    for (int i = (n - 2) / 2; i >= 0; --i)
    {
        AdjustDwon(a, n, i);
    }
    int end = n - 1;
    while (end > 0)
    {
        swap(&a[0], &a[end]);
        AdjustDwon(a, end , 0);
        --end;
    }
}

int GetMidIndex(int* a, int begin, int end)
{
    int mid = begin + ((end - begin) >> 1);
    if (a[begin] < a[mid])
    {
        if (a[mid] < a[end])
            return mid;
        else
        {
            if (a[begin] > a[end])
                return begin;
            return end;
        }
    }
    else
    {
        if (a[mid] > a[end])
            return mid;
        else
        {
            if (a[begin] > a[end])
                return begin;
            return end;
        }
    }
}

/ /快排
//  Hoare快排法
void QuickSort1(int* a,int left,int right)
{
    if (right <= left)
        return;
    int begin = left;
    int end = right;
    //取keyi方法
    
    //方法一:随机值法
    //int randi = rand() % (right - left + 1);
    //randi += left;
    //Swap(&a[randi], &a[left]);
    
    //方法二:三数取中法
    //int midi = GetMidIndex(a, begin, end);
    //Swap(&a[midi], &a[left]);
    int keyi = left;
    while (right > left)
    {
        while (right > left && a[right] >= a[keyi])
        {
            right--;
        }
        while (left < right && a[left] <= a[keyi])
        {
            left++;
        }
        Swap(&a[left], &a[right]);
    }
    Swap(&a[keyi], &a[left]);
    keyi = left;
    QuickSort1(a, begin, keyi - 1);
    QuickSort1(a, keyi + 1, end);
}


//  “双指针”法
void QuickSort2(int* a, int left, int right)
{
    if (right <= left)
        return;
    int prev = left;
    int cur = left + 1;
    int keyi = left;
    while (cur <= right)
    {
        if (a[cur] < a[keyi] && ++prev != cur)
        {
            Swap(&a[cur], &a[prev]);
        }
        cur++;
    }
    Swap(&a[prev], &a[keyi]);
    keyi = prev;
    QuickSort2(a, left, keyi - 1);
    QuickSort2(a, keyi + 1, right);
}

// 递归->非递归
void QuickSortNonR(int* a, int left, int right)
{
    ST st;
    STInit(&st);
    STPush(&st, right);
    STPush(&st, left);

    while (!STEmpty(&st))
    {
        int begin = STTop(&st);
        STPop(&st);

        int end = STTop(&st);
        STPop(&st);

        // 单趟
        int keyi = begin;
        int prev = begin;
        int cur = begin + 1;

        while (cur <= end)
        {
            if (a[cur] < a[keyi] && ++prev != cur)
                Swap(&a[prev], &a[cur]);

            ++cur;
        }

        Swap(&a[keyi], &a[prev]);
        keyi = prev;

        // [begin, keyi-1] keyi [keyi+1, end] 
        if (keyi + 1 < end)
        {
            STPush(&st, end);
            STPush(&st, keyi + 1);
        }

        if (begin < keyi - 1)
        {
            STPush(&st, keyi - 1);
            STPush(&st, begin);
        }
    }

    STDestroy(&st);

}

//归并排序

void _MergeSort(int* a, int begin, int end, int* tem)
{
    if (begin == end)
        return;
    int mid = (begin + end) / 2;
    int begin1 = begin, end1 = mid;
    int begin2 = mid + 1, end2 = end;
    _MergeSort(a, begin1, end1, tem);
    _MergeSort(a, begin2, end2, tem);
    int i = begin;
    while (begin1 <= end1&& begin2 <= end2)
    {
        if (a[begin1] <= a[begin2])
            tem[i++] = a[begin1++];
        else
            tem[i++] = a[begin2++];
    }
    while (begin1 <= end1)
    {
        tem[i++] = a[begin1++];
    }
    while (begin2 <= end2)
    {
        tem[i++] = a[begin2++];
    }
    memcpy(a + begin, tem + begin, sizeof(int)*(end - begin + 1));
}
void MergeSort(int* a, int n)
{
    int* tem = (int*)malloc(sizeof(int) * n);
    if (tem == NULL)
    {
        perror("malloc fail");
        return;
    }
    _MergeSort(a, 0, n - 1, tem);
    free(tem);
    tem = NULL;
}

//计数排序
void CountSort(int* a, int n)
{
    int min = a[0];
    int max = a[0];
    for (int i = 0; i < n; i++)
    {
        if (a[i] < min)
            min = a[i];
        if (a[i] > max)
            max = a[i];
    }
    int range = max - min + 1;
    int* Count = calloc(range,sizeof(int));
    if (Count == NULL)
    {
        perror("maloc fail");
        return;
    }
    for (int i = 0; i < n; i++)
    {
        Count[a[i] - min]++;
    }
    int j = 0;
    for (int i = 0; i < range; i++)
    {
        while (Count[i]--)
        {
            a[j++] = i + min;
        }
    }
}
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值