数据结构--排序

void Swap(int* a, int* b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}
//插入排序
//1、直接插入排序 - 从前往后比较
void InsertSort_1(int* ar, int left, int right)
{
    for (int i = left + 1; i < right; i++)
    {
        int k = left;
        while (ar[k] <= ar[i])
            k++;
        int tmp = ar[i];
        int j = i;
        for (j; j > k; j--)
            ar[j] = ar[j - 1];
        ar[j] = tmp;
    }
}
//2、直接插入排序 -- 从后往前比较
void InsertSort_2(int* ar, int left, int right)
{
    for (int i = left + 1; i < right; i++)
    {
        for (int j = i; j > left; j--)
        {
            if (ar[j - 1] > ar[j])
                Swap(&ar[j - 1], &ar[j]);
        }
    }
}


//3、直接插入排序 -- 从后往前比较,不调用交换函数
void InsertSort_3(int* ar, int left, int right)
{
    for (int i = left + 1; i < right; i++)
    {
        int tmp = ar[i];
        int j = i;
        while (j > left && ar[j - 1] > tmp)
        {
            ar[j] = ar[j - 1];
            j--;
        }
        ar[j] = tmp;
    }
}


//4、直接插入排序 -- 从后往前比较,带哨兵位
void InsertSort_4(int* ar, int left, int right)
{
    for (int i = left + 1; i < right; i++)
    {
        ar[0] = ar[i];
        int k = i;
        while (ar[k - 1] > ar[0])
        {
            ar[k] = ar[k-1];
            k--;
        }
        ar[k] = ar[0];
    }
}


//5、折半插入排序
void BinInsertSort(int* ar, int left, int right)
{
    for (int i = left + 1; i < right; i++)
    {
        int tmp = ar[i];
        int low = left;
        int high = i-1;
        while (low <= high)
        {
            int mid = (low + high)/2;
            if (tmp >= ar[mid])
                low = mid + 1;
            else
                high = mid - 1;
        }
        for(int j = i; j > low; j--)
            ar[j] = ar[j - 1];
        ar[low] = tmp;
    }
}


//Shell排序
void _ShellSort(int* ar, int left, int right, int gap)
{
    for (int i = left + gap; i < right; ++i)
    {
        int tmp = ar[i];
        int j = i;

        while (j > left && tmp < ar[j - gap])
        {
            ar[j] = ar[j - gap];
            j -= gap;
        }
        ar[j] = tmp;
    }
}
//分组
void _ShellSort(int* ar, int left, int right)
{
    int dlta[] = { 5,3,2,1 };  //素数
    int n = sizeof(dlta) / sizeof(dlta[0]);

    for (int i = 0; i < n; ++i)
    {
        _ShellSort(ar, left, right, dlta[i]);
    }
}

//Shell排序
void ShellSort(int* ar, int left, int right)
{
    int gap = right - left;
    while (gap > 1)
    {
        gap = gap / 3 + 1;//...5 3 2 1
        for (int i = left + gap; i < right; i++)
        {
            if (ar[i] < ar[i - gap])
            {
                int tmp = ar[i];
                int j = i;
                while(j > left&& tmp < ar[j - gap])
                {
                    ar[j]=ar[j - gap];
                    j = j - gap;
                }
                ar[j] = tmp;
            }
        }
    }
}
//选择排序 
//简单选择排序 
//寻找最小值下标
int GetMinIndex(int* ar, int left, int right)
{
    int index = 0;
    int min_value = ar[left];
    for (int i = left; i < right; i++)
    {
        if (ar[i] <=min_value )
        {
            min_value = ar[i];
            index = i;
        }
    }
    return index;
}
void SelectSort(int* ar, int left, int right)
{
    for (int i = left; i < right; i++)
    {
        int index = GetMinIndex(ar, i, right);
        if (index != i)
        {
            int tmp = ar[i];
            ar[i] = ar[index];
            ar[index] = tmp;
        }
    }
}

//堆排 
//向下调整
void _AdjustDownByHeapSort(int* ar, int left, int right, int start)
{
    int n = right - left;
    int i = start;
    //找左子树
    int j = 2 * i + 1;
    int tmp = ar[i];
    while (j < n)
    {
        if (ar[j + 1] < n && ar[j] < ar[j + i])
            j++;
        if (ar[j] > tmp)
        {
            ar[i] = ar[j];
            i = j;
            j = 2 * i + 1;
        }
        else
            break;
    }
    ar[i] = tmp;
}
void HeapSort(int* ar, int left, int right)
{
    //建堆(从小到大排序,建大堆)
    int n = right - left;
    //找到堆的最后一个分支
    int curpose = n / 2 - 1 + left;
    while (curpose >= left)
    {
        //向下调整
        _AdjustDownByHeapSort(ar, left, right, curpose);
        curpose--;
    }
    //排序
    for (int i = right-1; i >left; i--)
    {
        Swap(&ar[left], &ar[i]);
        _AdjustDownByHeapSort(ar, left, i-1, left);
    }
}

//交换排序 
//冒泡排序_1 
void BubbleSort(int* ar, int left, int right)
{
    for (int i = left; i < right; i++)
    {
        for (int j =left; j < right - i - 1; j++)
        {
            if (ar[j] > ar[j+1])
            {
                int tmp = ar[j];
                ar[j] = ar[j + 1];
                ar[j + 1] = tmp;
            }
        }
    }
}

//快速排序 - 挖坑法
//找分点
int _Parttition_1(int* ar, int left, int right)
{
    int low = left;
    int high = right - 1;
    int tmp = ar[low];
    while (low<high)
    {
        while (low<high && ar[high] >= tmp)
            high--;
        ar[low] = ar[high];
        while (low < high && ar[low] < tmp)
            low++;
        ar[high] = ar[low];
    }
    ar[low] = tmp;
    return low;
}

//快速排序 - 前后指针法 
int _Parttition_2(int* ar, int left, int right)
{
    int tmp = ar[left];
    int next = left;
    for (int prev = next+1; prev < right; prev++)
    {
        if (ar[prev] < tmp)
        {
            next++;
            if (next != prev)
                Swap(&ar[prev], &ar[next]);
        }
    }
    Swap(&ar[left], &ar[next]);
    return next;
}
//快速排序 - [三者取中] 
//将数组最左边,中间,最右边的值进行比较,取中间值。
int GetMidIndex(int* ar, int left, int right)
{
    int index = 0;
    int n = (right + left - 1) / 2;
    if (ar[left]<ar[n] && ar[right]>ar[n])
        index = n;
    else if (ar[n]<ar[left] && ar[right]>ar[left])
        index = left;
    else
        index = right - 1;;
    return index;
}
//找分点
int _Parttition_3(int* ar, int left, int right)
{
    //三者取中 
    int mid = GetMidIndex(ar, left, right);
    if (mid != left)
        Swap(&ar[mid], &ar[left]);
    int tmp = ar[left];
    int next = left;
    for (int prev = next + 1; prev < right; ++prev)
    {
        if (ar[prev] < tmp)
        {
            next++;
            if (next != prev)
                Swap(&ar[next], &ar[prev]);
        }
    }
    Swap(&ar[left], &ar[next]);
    return next;
}
//递归对分点两边分别进行排序
//在排序的元素数小于20时可以使用直接插入进行排序
void QuickSort_1(int* ar, int left, int right)
{
    if (left >= right)
        return;
    //int pos = _Parttition_1(ar, left, right);
    //int pos = _Parttition_2(ar, left, right);
    int pos = _Parttition_3(ar, left, right);
    QuickSort_1(ar, left, pos);
    QuickSort_1(ar, pos + 1, right);
}

//归并排序 
void _MergeSort(int* ar, int left, int right, int* tmp)
{
    //结束条件
    if (left >= right)
        return;
    //递归二分
    int mid = (left + right) / 2;
    _MergeSort(ar, left, mid, tmp);
    _MergeSort(ar, mid + 1, right , tmp);
    //重新归并
    int b1 = left, e1 = mid, b2 = mid + 1, e2 = right ,k=left;
    while (b1 <= e1 && b2 <= e2)
    {
        if (ar[b1] < ar[b2])
            tmp[k++] = ar[b1++];
        else
            tmp[k++] = ar[b2++];
    }
    while (b1 <= e1)
        tmp[k++] = ar[b1++];
    while (b2 <= e2)
        tmp[k++] = ar[b2++];
    //将数组tmp中的数据放回ar中
    memcpy(ar + left, tmp + left, sizeof(int) * (right - left + 1));
}
//归并排序
void MergeSort(int* ar, int left, int right)
{
    int n = right - left;
    int* tmp = (int*)malloc(sizeof(int)*n);
    _MergeSort(ar, left, right-1, tmp);
    free(tmp);
    tmp = NULL;
}
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值