多种排序介绍

//插入排序
//时间复杂度o(N^2)
void Insertsort(int *a,int n)
{
    for (int i = 0; i < n-1 ; i++)
    {
        int end = i;
        int tmp = a[end + 1];//保存end的后一个值
        while (end >= 0)
        {
            if (tmp < a[end])
            {
                a[end + 1] = a[end];
                end--;
            }
            else
            {
                break;
            }
        }
        a[end + 1] = tmp;
    }
    
}
//希尔排序
//1.预排序:分组插入排序
// 目的:大的更快换到后面,小的更快换到前面
//2.插入排序
//o(N^1.3)
void shellsort(int* a, int n)
{
    //预排序
    int gap = n;
    //gap越大,大的更到前面,越不接近有序
    while (gap > 1)
    {
        gap /= 3;
        gap += 1;
        for (int j = 0; j < gap; j++)
        {
            for (int i = j; i < n - gap; i += gap)
            {
                int end = i;
                int tmp = a[end + gap];
                while (end >= 0)
                {
                    if (tmp < a[end])
                    {
                        a[end + gap] = a[end];
                        end -= gap;
                    }
                    else
                    {
                        break;
                    }
                }
                a[end + gap] = tmp;
            }
        }
    }
    
    //和上面一样
    /*while (gap > 1)
    {
        gap /= 3;
        gap+=1;
        for (int i = 0; i < n - gap; i++)
        {
            int end = i;
            int tmp = a[end + gap];
            while (end >= 0)
            {
                if (tmp < a[end])
                {
                    a[end + gap] = a[end];
                    end -= gap;
                }
                else
                {
                    break;
                }
            }
            a[end + gap] = tmp;
        }
    }    */
}
void swap(int* p1, int* p2)
{
    int tmp = *p1;
    *p1 = *p2;
    *p2 = tmp;
}
//冒泡排序
//O(N^2)
void Bubblesort(int* a, int n)
{
    for (int i = 1; i <= n-1; i++)
    {
        bool flag = 0;
        for (int j = 1; j <= n - i; j++)
        {
            
            if (a[j - 1] > a[j])
            {
                flag = 1;
                swap(&a[j-1],&a[j]);
            }
        }
        if (!flag)
        {
            break;
        }
    }
}
void print(int* a, int n)
{
    for (int i = 0; i < n; i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");
}
void AdjustDown(int* a, int n, int parent)
{
    int child = parent * 2 + 1;
    while (child < n)
    {
        if (child + 1 < n && a[child + 1] < a[child])
        {
            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 - 1 - 1) / 2; i >= 0; i--)
    {
        AdjustDown(a, n, i);
    }
    int end = n - 1;
    while (end > 0)
    {
        swap(&a[0], &a[end]);
        AdjustDown(a, end, 0);
        --end;
    }
}


int getmidi(int* a, int left, int right)
{
    int mid = (left + right) / 2;
    if (a[left] < a[mid])
    {
        if (a[mid] < a[right])
        {
            return mid;
        }
        else if (a[left] > a[right])
        {
            return left;
        }
        else
        {
            return right;
        }
    }
    else//left >= mid
    {
        if (a[mid] > a[right])
        {
            return mid;
        }
        else if (a[left] < a[right])
        {
            return left;
        }
        else
        {
            return right;
        }
    }
}

//快速排序
//确定key,左边比key小,右边比key大
//时间复杂度:N*logN
//有序则会很慢O(N^2)
//递归会建立n*longN层栈帧
void quicksort(int* a, int left, int right)
{
    if (left >= right)
    {
        return;
    }


    //小区间优化
    /*if (right - left + 1 < 10)
    {
        Insertsort(a+left, right - left + 1);
    }
    else
    {*/
        int begin = left, end = right;

        //随机选key
        /*int randi = rand();
        randi %= (right-left);
        randi += left;
        swap(&a[left], &a[randi]);*///将第一个数弄成随机的数


        //三数取中//对有序的数排序快
        //left   mid   right
        /*int midi = getmidi(a, left, right);
        swap(&a[left], &a[midi]);*/


        int keyi = left;
        while (left < right)
        {
            while (a[right] >= a[keyi] && left < right)
            {
                --right;
            }
            while (a[left] <= a[keyi] && left < right)
            {
                left++;
            }
            swap(&a[left], &a[right]);
        }
        swap(&a[left], &a[keyi]);
        keyi = left;
        quicksort(a, begin, keyi - 1);
        quicksort(a, keyi + 1, end);
    //}
    
}


//选择排序
void selectsort(int *a,int n)
{
    int begin = 0, end = n - 1;
    while (begin < end)
    {
        int mmin = begin, mmax = begin;
        for (int i = begin + 1; i <= end; i++)
        {
            if (a[i] < a[mmin])
            {
                mmin = i;
            }
            if (a[i] > a[mmax])
            {
                mmax = i;
            }
        }
        swap(&a[begin], &a[mmin]);
        if (mmax == begin)
        {
            mmax = mmin;
        }
        swap(&a[end], &a[mmax]);
        begin++;
        end--;
        print(a, n);
    }
}


void quicksort2(int* a,int left,int right)
{
    if (left >= right)
    {
        return;
    }
    int keyi = left;
    int prev = left;
    int cur = left + 1;
    
    while (cur <= right)
    {
        if (a[cur] < a[keyi] && ++prev!=cur)
        {
            swap(&a[prev], &a[cur]);
        }
        cur++;
    }
    swap(&a[keyi], &a[prev]);
    keyi = prev;
    quicksort(a, left, keyi - 1);
    quicksort(a, keyi+1, right);
}

//快速排序非递归
//取栈顶区间,单趟排序,左右子区间入栈
//递归转非递归
void quicksort3(int* a,int left,int right)
{
    stack<int> st;
    st.push(right); 

    st.push(left);
    
    while (!st.empty())
    {
        int begin = st.top();
        st.pop();

        int end = st.top();
        st.pop();
        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)
        {
            st.push(end);
            st.push(keyi+1);
        }
        if (begin < keyi - 1)
        {
            st.push(keyi - 1);
            st.push(begin);
        }
    }

    /*while (!st.empty())
    {
        st.pop();
    }*/
}
 
 
//N*logN的时间复杂度
//归并排序
void _mergesort(int* a, int begin,int end,int*tmp)
{
    if (begin == end)
    {
        return;
    }
    int mid = (begin + end) / 2;
    //[begin,mid]  [mid+1,end]
    _mergesort(a, begin, mid ,tmp);
    _mergesort(a, mid + 1, end,tmp);
    //归并逻辑
    int begin1 = begin;
    int end1 = mid;
    int begin2 = mid + 1;
    int end2 = end;
    int i = begin;
    //取小的尾插到tmp数组
    while (begin1 <= end1 && begin2 <= end2)
    {
        if (a[begin1] < a[begin2])
        {
            tmp[i++] = a[begin1++];
        }
        else
        {
            tmp[i++] = a[begin2++];
        }
    }
    while (begin1 <= end1)
    {
        tmp[i++] = a[begin1++];
    }
    while (begin2 <= end2)
    {
        tmp[i++] = a[begin2++];
    }
    memcpy(a + begin, tmp + begin, sizeof(int)*(end - begin + 1));
}
void mergesort(int* a, int n)
{
    int* tmp = (int*)malloc(sizeof(int) * n);
    if (tmp == NULL)
    {
        perror("malloc failed");
        return;
    }

    _mergesort(a,0, n-1,tmp);
    free(tmp);
    tmp = NULL;
}

//归并排序非递归

void mergesortnor(int* a, int n)
{
    int* tmp = (int*)malloc(sizeof(int) * n);
    if (tmp == NULL)
    {
        perror("malloc failed");
        return;
    }
    int gap = 1;
    while (gap < n)
    {
        for (int j = 0; j < n; j += 2 * gap)
        {
            int begin1, end1, begin2, end2;
            begin1 = 0, end1 = begin1 + gap - 1;
            begin2 = end1 + gap, end2 = begin2 + gap - 1;
            if (end1 >= n || begin2 >= n)
            {
                break;
            }
            if (end2 >= n)
            {
                end2 = n - 1;
            }
            int i = j;
            while (begin1 <= end1 && begin2 <= end2)
            {
                if (a[begin1] < a[begin2])
                {
                    tmp[i++] = a[begin1++];
                }
                else
                {
                    tmp[i++] = a[begin2++];
                }
            }
            while (begin1 <= end1)
            {
                tmp[i++] = a[begin1++];
            }
            while (begin2 <= end2)
            {
                tmp[i++] = a[begin2++];
            }
            memcpy(a + j, tmp + j, sizeof(int) * (end2 - j + 1));
        }
        gap *= 2;
    }
    free(tmp);
    tmp = NULL;
}


//非比较排序
//小众
//计数排序
//[6,1,2,1,9,6]
//1.统计每个数据出现的次数  s[a[i]]++
//2.遍历s数组
//适合数据范围集中的数组进行排序,不适合数据分散的
//数组范围按照最大值减最小值来开空间
void countsort(int* a, int n)
{
    int mmin = a[0], mmax = a[0];
    for (int i = 1; i < n; i++)
    {
        if (mmin > a[i])
        {
            mmin = a[i];
        }
        if (mmax < a[i])
        {
            mmax = a[i];
        }
    }
    int range = mmax - mmin + 1;
    int* count = (int*)malloc(sizeof(int) * range);
    if (count == NULL)
    {
        perror("malloc fail");
        return;
    }
    memset(count, 0, sizeof(int) * range);
    for (int i = 0; i < n; i++)
    {
        count[a[i] - mmin]++;
    }
    int j = 0;
    for (int i = 0; i < range; i++)
    {
        while (count[i]--)
        {
            a[j++] = mmin + i;
        }
    }


}

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值