各类排序以及折半查找

整理各类排序算法以及二分查找如下:

//直接插入排序

//时间复杂度:O(n^2);空间复杂度:O(1);稳定;
//越有序查找速度越快:O(n)

void Insert_sort(int *arr,int len)
{
    int i;
    int j;
    int tmp;

    for(i = 1 ; i < len ; ++i)
    {
        tmp = arr[i];
        for(j = i - 1 ; j >=0 ; --j)
        {
            if(arr[j] > tmp)
            {
                arr[j+1] = arr[j];
            }
            else
            {
                arr[j+1] = tmp;
                break;
            }
        }
        arr[j+1] = tmp;
    }
}

//希尔排序

,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本
//分组+直接插入
//时间复杂度:O(n^1.3~1.5);空间复杂度:O(1);不稳定;

void Shell(int *arr,int len,int gap)
{
    int tmp;
    for(int i = gap ; i < len ; ++i)
    {
        tmp = arr[i];
        int j;
        for(j = i - gap ; j >=0 ; j -= gap)
        {
            if(arr[j] > tmp)
            {
                arr[j + gap] = arr[j];
            }
            else
                break;
        }
        arr[j + gap] = tmp;
    }
}
void Shell_sort(int *arr,int len)
{
    int d[] = {5,3,1};
    for(int i = 0 ; i < sizeof(d)/sizeof(d[0]) ; ++i)
    {
        Shell(arr,len,d[i]);
    }
}

//冒泡排序

//时间复杂度:O(n^2);空间复杂度:O(1);稳定;

void Bubble_sort(int *arr,int len)
{
    for(int i = 0 ; i < len - 1 ; ++i)
    {
        for(int j = 0 ; j < len - i - 1 ; ++j)
        {
            if(arr[j] > arr[j+1])
            {
                int tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp;
            }
        }   
    }
}

//快速排序

,平均性能最快,有序时效率最低,退化为选择排序时间复杂度:O(n^2)
//一次快排后,基准左侧小于基准,右侧大于基准,可用来分离奇偶数
//时间复杂度:O(n*log);空间复杂度:O(log);不稳定;

int  Quick_part(int *arr,int low,int high)
{
    int tmp = arr[low];
    while(low < high)
    {
        while(low < high && arr[high] >= tmp)
            high--;
        arr[low] = arr[high];

        while(low < high && arr[low] <= tmp)
            low++;
        arr[high] = arr[low];
    }

    arr[low] = tmp;
    return low;
}
void Quick(int *arr,int low,int high)
{
    int par = Quick_part(arr,low,high);
    if(low < par - 1)
        Quick(arr,low,par-1);
    if(high > par + 1)
        Quick(arr,par+1,high);
}
void Quick_sort(int *arr,int len)
{
    Quick(arr,0,len-1);
}

//直接选择排序

//每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后
//时间复杂度:O(n^2);空间复杂度:O(1);不稳定;

void Select_sort(int *arr,int len)
{
    int tmp;
    int minindex;
    for(int i = 0 ; i < len ; ++i)
    {
        minindex = i;
        for(int j = i + 1 ; j < len ; ++j)
        {
            if(arr[minindex] > arr[j])
                minindex = j;
        }

        tmp = arr[i];
        arr[i] = arr[minindex];
        arr[minindex] = tmp;
    }
}

//堆排序

:树形选择排序
//处于最大堆的根节点的元素一定是这个堆中的最大值
//每次都取堆顶的元素,将其放在序列最后面,然后将剩余的元素重新调整为最大堆
//时间复杂度:O(n*log);空间复杂度:O(1);不稳定;
//最好情况下,时间复杂度为O(1).

void HeapAdjust(int *arr,int start,int end)//时间复杂度:O(log);空间复杂度:O(1)
{
    int tmp = arr[start];//根节点的值
    int parent = start;

    for(int i = 2*start+1 ; i <= end ; i = 2*i+1)//下一跳至左孩子
    {
        if(i+1 <= end && arr[i] < arr[i+1])//若有右孩子,跳至左右孩子中较大值处
            i++;

        if(arr[i] > tmp)
        {
            arr[parent] = arr[i];//若子节点数值大于父节点,将值赋给父节点
            parent = i;//父节点向下移动
        }
        else
            break;
    }
    arr[parent] = tmp;
}

void Heap_sort(int *arr,int len)
{
    for(int i = (len - 2)/2 ; i >= 0 ; --i)
        HeapAdjust(arr,i,len-1);//第一次建立大根堆,从最后一颗子树开始,从后往前调整

    //此时根节点最大
    int tmp;
    for(int i = 0 ; i < len - 1 ; ++i)
    {
        tmp = arr[0];
        arr[0] = arr[len-1-i];
        arr[len-1-i] = tmp;

        HeapAdjust(arr,0,len-i-2);//自上到下调整
    }
}

//归并排序

:归并是指将若干个已排序的子文件合并成一个有序的文件
//时间复杂度:O(n*log);空间复杂度:O(n);稳定;

void Merge(int *arr,int len,int gap)//时间复杂度:O(n*log)
{
    int low1 = 0;//第一个归并段的起始下标
    int high1 = low1+gap-1;//第一个归并段的结尾下标
    int low2 = high1+1;//第二个归并段的起始下标
    int high2 = low2+gap<len?low2+gap-1:len-1;//第二个归并段的结尾下标
    int *brr = (int *)malloc(len*sizeof(int));
    int i = 0;//brr下标

    //归并段成对
    while(low2 < len)
    {
        //两个归并段都还有数据
        while(low1<=high1 && low2<=high2)
        {
            if(arr[low1] <= arr[low2])
            {
                brr[i++] = arr[low1++];
            }
            else
            {
                brr[i++] = arr[low2++];
            }
        }

        //一个归并段已完成另一个还有数据
        while(low1 <= high1)
        {
            brr[i++] = arr[low1++];
        }

        while(low2 <= high2)
        {
            brr[i++] = arr[low2++];
        }

        low1 = high2+1;
        high1 = low1+gap-1;
        low2 = high1+1;
        high2 = low2+gap<len?low2+gap-1:len-1;
    }

    //不成对的归并段
    while(low1 < len)
    {
        brr[i++] = arr[low1++];
    }

    for(i = 0 ; i < len ; i++)      
    {
        arr[i] = brr[i];
    }
    free(brr);
}
void Merge_sort(int *arr,int len)
{
    for(int i = 1 ; i < len ; i *= 2)
    {
        Merge(arr,len,i);
    }
}
void Show(int *arr,int len)
{
    for(int i = 0 ; i < len ; ++i)
    {
        cout<<arr[i]<<" ";
    }
    cout<<endl;
}
//二分查找  有序方可
int Search(int *arr,int len,int key)
{
    if(arr == NULL || len <= 0)
        return -1;

    int left = 0;
    int right = len - 1;
    int mid;

    while(left <= right)
    {
        mid = (right - left) / 2 + left;
        if(arr[mid] == key)
        {
            return mid;
        }
        else if(arr[mid] < key)
        {
            left = mid +1;
        }
        else
        {
            right = mid - 1;
        }
    }

    return -1;
}

以上代码均运行无误:

int main()
{
    int arr[] = {24,10,45,8,5,17,29,2,57};
    int len = sizeof(arr)/sizeof(arr[0]);

    //Insert_sort(arr,len);
    //Shell_sort(arr,len);
    //Bubble_sort(arr,len);
    //Quick_sort(arr,len);
    //Select_sort(arr,len);
    //Heap_sort(arr,len);
    Merge_sort(arr,len);
    Show(arr,len);

    cout<<Search(arr,len,57);
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值