各种排序算法C++实现

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

//插入排序
void InsertSort(int* num, int len)
{
    for(int i=0; i<len-1; i++)
    {
        for(int j=i+1; j>0; j--)
        {
            if(num[j] < num[j-1])
                swap(num[j],num[j-1]);
            else
                break;
        }
    }
}

//冒泡排序
void BubbleSort(int* num, int len)
{
    //问题:若中途数据排序好后,程序还会继续运行
    //优化,设置标志位,如果某轮比较过程中没有发生交换,则结束
    bool flag;
    for(int i=0; i<len-1; i++)
    {
        flag = false;
        for(int j=len-1; j>i; j--)
        {
            if(num[j] < num[j-1])
            {
                swap(num[j],num[j-1]);
                flag = true;
            }
        }
        if(!flag)
            break;
    }
}

//选择排序
void SelectSort(int* num, int len)
{
    for(int i=0; i<len; i++)
    {
        for(int j=i+1; j<len; j++)
        {
            if(num[j] < num[i])
                swap(num[j],num[i]);
        }
    }
}
//快速排序   挖坑分治法,通过挖坑将数据分为两块(先从右往左挖)
void QuickSort(int* num, int left, int right)
{
    if(left < right)
    {
        int i = left, j = right, key = num[left];
        while(i < j)
        {
            //找到从右边数第一个数
            while(i<j && num[j] >= key)
                j--;
            //将这个数填到i处, j 处空缺
            if(i < j)
                num[i++] = num[j];

            while(i<j && num[i] < key)
                i++;
            if(i < j)
                num[j--] = num[i];
        }
        //一次排序完毕,将key的位置确定
        num[i] = key;
        QuickSort(num, left,i-1);
        QuickSort(num, i+1,right);
    }
}

//希尔排序
//分为n个gap,每个gap插入排序
void ShellSort(int* num, int len)
{
    int gap;

    for(gap = len/2; gap>0; gap/=2)
        for(int i=0; i<gap; i++)//gap个序列插入排序
        {
            for(int j = i+gap; j<len; j+=gap)//插入排序
            {
                for(int k=j; k>i; k-=gap)
                {
                    if(num[k] < num[k-gap])
                        swap(num[k], num[k-gap]);
                    else
                        break;
                }
            }
        }
}

//归并排序 分为sort过程和merge过程
//merge过程,将两个有序数组有序放入temp数组,然后拷贝到原数组
void Merge(int* num,int left, int mid, int right, int* tmp)
{
    int i = left;
    int j = mid+1;
    int t = 0;
    while(i<=mid && j<=right)
    {
        if(num[i] < num[j])
            tmp[t++] = num[i++];
        else
            tmp[t++] = num[j++];
    }
    while(i<= mid)
        tmp[t++] = num[i++];
    while(j<= right)
        tmp[t++] = num[j++];

    t = 0; //将辅助数组tmp拷贝到num
    while(left <= right)
        num[left++] = tmp[t++];
}
void MergeSort(int* num, int left, int right, int* tmp)
{
    if(left < right)
    {
        int mid = (left + right)/2;
        MergeSort(num,left,mid,tmp);
        MergeSort(num,mid+1,right,tmp);
        Merge(num,left,mid,right,tmp);
    }
}

//堆排序
//思路:
//a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
//b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
//c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

//调整大根堆
void adjustHeap(int* num, int left, int right)
{
    int temp = num[left];//取出当前元素,以便与它的子孙节点交换

    //从第一个非叶子结点从下至上,从右至左调整结构
    for(int i = left*2+1;/*直接左孩子*/ i<right; i = i*2+1)
    {
        //左孩子节点小于右孩子节点
        if(i+1 < right && num[i] < num[i+1])
            i++;

        //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
        if(num[i]> temp)
        {
            num[left] = num[i];
            left = i;
        }
        else
            break;
    }

    //将temp值放到最终的位置
    num[left] = temp;
}
//堆排序
void HeapSort(int* num, int len)
{
    //1、构建大根堆(每一个非叶子节点从下至上,从右至左)
    for(int i = len/2-1; i>=0; i--)
        adjustHeap(num,i,len);

    //2、交换堆顶元素和末位元素,继续调整大根堆
    for(int i = len-1; i>=0; i--)
    {
        swap(num[0],num[i]);
        adjustHeap(num,0,i);
    }

}

int main()
{
    int num[] = {1,3,5,7,9,2,4,6,8,10};
    //sort(num,num+10);
    //InsertSort(num,10);
    //BubbleSort(num,10);
    //SelectSort(num,10);
    //QuickSort(num,0,9);
    //ShellSort(num,10);

    //int tmp[11];
    //MergeSort(num,0,9,tmp);
    //HeapSort(num,10);

    for(int i=0; i<10; i++)
        cout<<num[i]<<" ";
    cout<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值