常见的排序算法实现

目录

前言

插入排序

1.直接插入排序

2.折半插入排序

3.希尔排序

交换排序

1.冒泡排序

2.快速排序

选择排序

1.简单选择排序

2.堆排序

 二路归并排序

算法总结

前言

        本文部分代码参考2022年王道数据结构实现,所有代码均可运行。

插入排序

1.直接插入排序

void display(int a[],int n)
{
    for(int i = 0; i < n; ++i)
        cout<<a[i]<<" ";
    cout<<endl;
}

void dinsert(int a[],int n)
{
    int temp = 0,i,j;
    for(i = 0; i < n-1;++i)
    {
        // 如果不是有序的话,那么找到合适的位置
        if(a[i] > a[i+1])
        {
            temp = a[i+1];
            for(j = i; temp < a[j] && j >= 0; --j)
            {
                a[j+1] = a[j];
            }
            a[j+1] = temp; //先--再跳出去的,所以需要j+1
        }
    }
    display(a,n);
}

2.折半插入排序

void display(int a[],int n)
{
    for(int i = 0; i < n; ++i)
        cout<<a[i]<<" ";
    cout<<endl;
}

void binarysort(int a[], int n)
{
    int temp,i,j,low,high,mid;
    for(i = 1;i < n;++i)
    {
        low = 0,high = i-1; // 在0至i-1的范围内视为有序区,i代表新的待插数
        temp = a[i];
        // 在有序区内进行二分查找
        while(low <= high)
        {
            mid = (low + high)/2;
            if(a[mid] > temp)
                high = mid -1;
            else 
               low = mid + 1;
        }
        // 移动位置,high+1就是mid的位置,也就是我们需要插入的位置
        for(j = i-1;j >= high +1; --j)
        {
            a[j+1] = a[j];
        }
        a[high+1] = temp;
    }
    display(a,n);
}

3.希尔排序

void display(int a[],int n)
{
    for(int i = 0; i < n; ++i)
        cout<<a[i]<<" ";
    cout<<endl;
}

void shellsort(int a[],int n)
{
    int d ,i,j,k,temp;//首先是分成一半进行排序
    for(d = n/2; d >= 1; d/=2)
    {
        for(i = d; i < n; ++i) //多组同时进行遍历
        {
            if(a[i] < a[i-d])
            {
                temp = a[i];
                for(j = i-d; j >= 0 && temp < a[j]; j -= d)
                {
                    a[j+d] = a[j];
                }
                a[j+d] = temp;
            }
        }
    }
    display(a,n);
}

交换排序

1.冒泡排序

void display(int a[],int n)
{
    for(int i = 0; i < n; ++i)
        cout<<a[i]<<" ";
    cout<<endl;
}

void swap(int &a,int &b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}

void bubblesort(int a[],int n)
{
    int i,j;
    for(i = 0; i < n; ++i)
    {
        for(j = i+1; j < n; ++j)
        {
            if(a[i] > a[j])
                swap(a[i],a[j]);
        }
    }
    display(a,n);
}

2.快速排序

void quicksort(int a[],int low,int high)
{
    if(low >= high) // 超出处理范围了
        return;
    int pivot = a[low],left = low,right = high;
    while(low < high)  // 反复寻找,直至将这次范围内的数都排到轴的左右
    {
        while (a[high] > pivot && low < high)  // 找到比pivot大的数
           --high;
        a[low] = a[high];   // pivot的数据就是low的数据所以可以直接存
        while (a[low] <= pivot && low < high)  //找到小于或等于pivot的数
            ++low;
        a[high] = a[low]; // low经过上面的while语句指向了不符合要求的数,所以用high来存它
        //通过上面两个赋值语句,不符合要求的数就被交换了
    }
    a[low] = pivot;  
    //从上述语句跳转出来,low处的值必定被保存了,而且low此时的位置是数组以pivot为中心的中间部分
    // 所以使用low处来存pivot
    quicksort(a,left,low-1);
    quicksort(a,low+1,right); 
}

选择排序

1.简单选择排序

void display(int a[],int n)
{
    for(int i = 0; i < n; ++i)
        cout<<a[i]<<" ";
    cout<<endl;
}



void selectsort(int a[],int n)
{
    int i,j,k;
    for(i = 0; i < n; ++i)
    {
        k = i;
        for(j = i+1; j < n; ++j)
        {
            if(a[k] > a[j])
                k = j;
        }
        swap(a[i],a[k]);
    }
    display(a,n);
}

2.堆排序

void display(int a[],int n)
{
    for(int i = 0; i < n; ++i)
        cout<<a[i]<<" ";
    cout<<endl;
}

void swap(int &a,int &b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}

void construct_heap(int a[],int start, int end)
{
    // 完全二叉树的知识,父节点与子节点
    int father = start;
    int son = 2*start+1;
    // 当达到遍历的界限时
    while (son <= end)
    {
        if(son+1 <= end && a[son] < a[son+1])  //选择最大的子节点
            son++;
        if(a[father] > a[son])  //如果已经是一颗大根堆了,就不需要继续遍历了
            return ;
        else
        {
            swap(a[father],a[son]);  //进行交换,成为大根堆
            //继续往下遍历,完善大根堆
            father = son;
            son = son*2 + 1;
        }
    }
    
}

void heapsort(int a[],int n)
{
    int i;
    for(i = n/2 - 1; i >= 0; --i) //从比较小的树一步步往上建立
        construct_heap(a,i,n-1);
    for(i = n-1; i > 0; --i)  // 0处存储的值都是每次选出来的最大值
    {
        swap(a[0],a[i]);
        construct_heap(a,0,i-1);  //重新进行大根堆的建立,这次由于0节点改变,所以直接从整棵树开始建立
        //减小遍历的范围
    }
display(a,n);
}

 二路归并排序

void merge(int a[],int low, int mid, int high)
{
    int i = 0,j,k = low;
    //存储起来
    for(i = low; i <= high; ++i)
        b[i] = a[i];
    for(i = low,j = mid + 1;i <= mid && j <= high ;k++)
    {
        if(b[i] > b[j])
        {
            a[k] = b[j];
            ++j;
        }
        else
        {
            a[k] = b[i];
            ++i;
        }
    }
    while(i <= mid)
    {
        a[k] = b[i];
        ++i;++k;
    }
    while(j <= high)
    {
        a[k] = b[j];
        ++j;++k;
    }
}

void mergesort(int a[],int low, int high)
{
    if(low < high)
    {
        int mid = (low+high)/2;
        mergesort(a,low,mid);//对左半部分排序
        mergesort(a,mid+1,high);//对右半部分排序
        merge(a,low,mid,high);//将排序后的结果合并
    }

}

算法总结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值