算法2——排序

#include<iostream>
#include<iomanip>
#include<cmath>
#include<string.h>
#include<cstdlib>
using namespace std;

//插入排序
// 1.直接插入 
// a.记录被插入的值 temp
// b.插入次数 i
// c.插入位置 pos
// d.大于插入数移动从i-1到pos都往后移动
// 时间复杂度o(n*n),空间复杂度o(1)
void insert_sort(int arr[],int n)
{
    int i,pos,temp;
    for(i=1;i<n;i++)
    {
        //找坐标
        temp = arr[i];
        pos = i;
        while(arr[--pos]>temp&&pos>=0);
        //后移
        for(int j = i-1;j>pos;j--)
        {
            arr[j+1] = arr[j];
        }
        arr[pos+1] = temp;
    }
}
void insert_sort_1(int arr[],int n)
{
    int i,j,temp;
    for(i=1;i<n;i++)
    {
        //找坐标
        if(arr[i]<arr[i-1])
        {
            temp = arr[i];
            //后移
            for(int j = i-1;j>=0&&arr[j]>temp;j--)
            {
                arr[j+1] = arr[j];
            }
            arr[j+1] = temp;
        }
        
    }
}
// 2.折半插入
void insert_sort_2(int arr[],int n)
{
    int i,pos,temp;
    for(i = 1;i<n;i++)
    {
        temp = arr[i];
        //折半查找
        int left = 0,right = i-1;
        while(left<=right)
        {
            int mid = (left+right)/2;
            if(arr[mid]<temp)left = mid+1;
            else right = mid-1;
        }
        pos = right;
        //后移
        for(int j = i-1;j>pos;j--)
        {
            arr[j+1] = arr[j];
        }
        arr[pos+1] = temp;
    }
}
// 3.希尔排序
// 1.循环步长,/2直到步长为1
// 2.对于每个步长进行插入排序
// 空间复杂度o(1),时间复杂度约为(n的1.3次方)
// 不稳定
void shell_sort(int arr[],int n)
{
    int d,i,j,temp;
    for(d = n/2;d>=1;d/=2)
    {
        //单步插入
        for(i =d;i<n;i++)
        {
            if(arr[i-d]>arr[i])
            {
                temp = arr[i];
                for(j =i-d;j>=0&&arr[j]>temp;j-=d)
                {
                    arr[j+d] = arr[j];
                }
                arr[j+d] =temp; 
            }
    
        }
    }
}
// 交换排序
// 1.冒泡排序
// a.循环次数n-1,每次会找到一个最大值放到最后;
// b.交换n-1-i次
// 空间复杂度o(1),时间复杂度最好o(n),最坏为o(n*n)
// 稳定,适用于链表
void bubble_sort(int arr[],int n)
{
    int i,j,temp;
    for(i =0;i<n;i++)
    {
        int flag = 1;
        for(j =0;j<n-1-i;j++)
        {
            if(arr[j]>arr[j+1])
            {
                temp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = temp;
                flag = 0;
            }
        }
        if(flag)break;
    }
}

//快速排序
// 1.单次划分函数part(int arr[],int left,int right)
// 2.递归左右划分,出口是left==right
// 时间复杂度最好o(n*log2 n),最差o(n*n);空间复杂度最好o(n*log2 n),最差o(n*n)
int part(int arr[],int left,int right)
{
    int mul = arr[left];
    while(left<right)
    {
        while(left<right&&arr[right]>=mul)right--;//找到小值
        arr[left] = arr[right];
        while(left<right&&arr[left]<mul)left++;
        arr[right] = arr[left];
    }
    arr[left] = mul;
    return left;
}
void quick_sort(int arr[],int left,int right)
{
    if(left<right)
    {
        int mul = part(arr,left,right);
        quick_sort(arr,left,mul-1);
        quick_sort(arr,mul+1,right);

    }
}
//选择排序
//1.简单选择排序
// a.循环n-1次
// b.每次找到最小值放在前面
//时间复杂度o(n*n)无法优化,不稳定
void select_sort(int arr[],int n)
{
    int i,j,min,item;
    for(i =0;i<n-1;i++)
    {
        min =i;
        for(j=i;j<n;j++)
        {
            if(arr[j]<arr[min])min =j;
        }
        //交换
        item = arr[min];
        arr[min] = arr[i];
        arr[i] = item;
    }
}

//2.堆排序(感觉特别厉害)
// a.将每个大根堆的首元素放在最后
// b.将剩下元素进行首元素大根堆排序
// c.需要节点子数大根堆函数,数组大根堆函数,最后组装在大根堆排序中
// 时间复杂度为o(n*log2 n),空间复杂度o(1)
void max_one(int arr[],int k,int len)
{
    int i,temp;
    temp = arr[k];
    
    for(i =2*k;i<=len;i*=2)
    {
        //找到两个孩子最大
        if(i<len&&arr[i]<arr[i+1])i++;
        if(temp>arr[i])break;//当时写成了arr[k]>arr[i]弄了好久
        else//交换
        {
            arr[k] = arr[i];
            k = i;
        }
    }
    arr[k] = temp;
}
void max_arr(int arr[],int len)
{
    for(int i=len/2;i>0;i--)
    {
        max_one(arr,i,len);
    }
}
void max_sort(int arr[],int len)
{
    max_arr(arr,len);
    for(int i =len;i>0;i--)
    {
        int temp = arr[i];
        arr[i] = arr[1];
        arr[1] = temp;
        max_one(arr,1,i-1);
    }
}

//试一试小根堆
// a.将最小根第一项保留,继续剩下形成小跟堆
// b.节点子树小根堆上升
// 代码有点问题(之后改)
void print_arr(int arr[],int len)
{
    for(int i =1;i<=len;i++)
    {
        cout<<arr[i]<<' ';
    }
    cout<<endl;
}
void min_one(int arr[],int k,int len)
{
    int i,temp;//记录最小位置和初始值
    temp = arr[k];
    for(i = 2*k;i<=len;i*=2)
    {
        //最小
        if(i<len&&arr[i]>arr[i+1])i++;
        if(temp<arr[i])break;
        else
        {
            arr[k] = arr[i];
            k = i;
        }
    }
    arr[k] = temp;
}
void min_arr(int arr[],int len)
{
    for(int i = len/2;i>0;i--)
    {
        min_one(arr,i,len);
    }
}
void min_sort(int arr[],int len)
{
    for(int i =len;i>0;i--)
    {
        int temp = arr[i];
        arr[i] = arr[1];
        arr[1] = temp;
        min_one(arr,1,i-1);
        print_arr(arr,len);
    }
}

//归并排序
//时间复杂度o(n*log2 n)空间复杂度o(n)
//1.两个有序数组合并
int brr[100];
void merge(int arr[],int left,int mid,int right)
{
    int i,j,k;
    for(i =left;i<=right;i++)
    {
        brr[i] = arr[i];
    }
    for(i = left,j =mid+1,k =left;i<=mid&&j<=right;k++)
    {
        if(brr[i]<=brr[j])arr[k] = brr[i++];
        else arr[k] = brr[j++];
    }
    while(j<=right)arr[k++] = brr[j++];
    while(i<=mid)arr[k++] = brr[i++];
}
void merge_sort(int arr[],int left,int right)
{
    if(left<right)
    {
        int mid = (left+right)/2;
        merge_sort(arr,left,mid);
        merge_sort(arr,mid+1,right);
        merge(arr,left,mid,right);
    }
}
// //计数排序
// 1.记录数组最大最小值,开辟一个大小为max-min的数组
// 2.记录坐标次数
// 3.打印序号+min
void count_sort(int arr[],int len)
{
    int min = 100,max = 0;
    for(int i=0;i<len;i++)
    {
        if(arr[i]<min)min = arr[i];
        if(arr[i]>max)max = arr[i];
    }
    int d = max-min+1;
    int *b = new int[d];
    memset(b,0,d*sizeof(int));
    for(int i =0;i<len;i++)
    {
        b[arr[i]-min]++;
    }
    for(int i =0;i<d;i++)
    {
        while(b[i]--)
        {
            cout<<i+min<<" ";
        }

    }
    delete []b;
}
int main()
{
    int arr[] = {134,349,24,576,854,23,5,78,-7};
    int n = sizeof(arr)/sizeof(arr[0]);
    // insert_sort_2(arr,n);
    // shell_sort(arr,n);
    // bubble_sort(arr,n);
    // quick_sort(arr,0,n-1);
    // select_sort(arr,n);
    // max_sort(arr,n-1);//精彩,太精彩了!
    // min_arr(arr,n-1);
    // min_sort(arr,n-1);
    // merge_sort(arr,0,n-1);
    count_sort(arr,n);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值