排序(直接排序,快排,希尔排序,归并排序)

1.直接插入排序:基本算法:将第i个记录插入到前面第i-1个已经排好序的记录中。当插入第i(i>.=1)个元素时,前面的元素已经排好序,此时用array[i]与前面的元素进行比较,找到插入位置之后将array[i]插入,原来的位置上的元素顺序后移。
这里写图片描述
具体代码实现为:

#include<iostream>
using namespace std;
void InsertSort(int *array, size_t size)
{
    //每一趟
    for (int i = 1; i < size; i++)//依次插入元素
    {
        int key = array[i];
        int end = i - 1;
        while (end>=0 && key < array[end])
        {
            array[end + 1] = array[end];
            end--;
        }
        array[end + 1] = key;//插入元素
    }
}
int main()
{
    int array[] = { 8, 2, 6, 7, 9, 10 };
    int sz = sizeof(array) / sizeof(array[0]);
    InsertSort(array, sz);
    for (size_t i = 0; i < sz; i++)
    {
        cout << array[i] << endl;
    }
    system("pause");
    return 0;
}

2.二分查找排序
这里写图片描述
具体的代码实现为:

void Insert_BinarySearchSort(int *array, size_t size)
{
    for (int  i = 1; i < size; i++)
    {
        int left = 0;
        int right = i - 1;
        int key = array[i];
        int mid = 0;
        while (left <= right)
        {
             mid = left + ((right - left) >> 1);
            if (key < array[mid])
            {
                right = mid - 1;
            } 
            else
            {
                left = mid + 1;
            }
        }
        //搬移元素
        int end = i - 1;
        while (end >= left)//将left当前位置的元素搬走
        {
            array[end + 1] = array[end];
            end--; 
        }
        //插入元素
        array[left] = key;
    }
}
int main()
{
    int array[] = { 8, 2, 6, 7, 9, 10 };
    int sz = sizeof(array) / sizeof(array[0]);
    Insert_BinarySearchSort(array, sz);
    for (int i = 0; i < sz; i++)
    {
        cout << array[i] << endl;
    }
    system("pause");
    return 0;
}

3.希尔排序(Shell 排序)
希尔排序是插入排序的一种又称“缩小增量排序”,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。
方式1:基于直接插入排序进行修改,分组进行。
这里写图片描述
这里写图片描述
这里写图片描述
具体的代码实现为:

void ShellSort(int *array, size_t size)
{
    int gap = 3;
    while (gap)
    {
        for (int i = gap; i < size; i++)
        {
            int end = i - gap;
            int key = array[i];
            while (end>=0 && key < array[end])//end>0避免end越界  
            {
                array[end + gap] = array[end];
                end-=gap;
            }
            array[end + gap] = key;
        }
        gap--;
    }
}
int main()
{
    int array[] = { 8, 2, 6, 7, 9, 10 };
    int sz = sizeof(array) / sizeof(array[0]);
    ShellSort  (array, sz);
    for (int i = 0; i < sz; i++)
    {
        cout << array[i] << endl;
    }
    system("pause");
    return 0;
}

2.方式二:

void ShellSort(int *array, size_t size)
{
    int gap = size;
    while (gap>1)
    {
        gap = gap / 3 + 1;
        for (size_t i = gap; i < size; i++)
        {
            int key = array[i];
            int end = i - gap;
            //找当前元素需要插入的位置  
            while (end >= 0 && key < array[end])//end>0避免end越界  
            {
                array[end + gap] = array[end];//往后搬移  
                end -= gap;
            }
            array[end + gap] = key;
        }
    }
}
int main()
{
    int array[] = { 8, 2, 6, 7, 9, 10 };
    int sz = sizeof(array) / sizeof(array[0]);
    ShellSort  (array, sz);
    for (int i = 0; i < sz; i++)
    {
        cout << array[i] << endl;
    }
    system("pause");
    return 0;
}

4.选择排序:
基本算法思想:第i趟(i=0,1,2…)在n-i个待排序的数据元素集合中选出关键码最小的数据元素 ,作为有序元素序列的第i个元素,待到第n-2趟做完,待排序元素集合中只剩下1个元素,排序结束。
(1)、直接选择排序:

先从第一个元素给予maxpos,依次进行比较,若后面元素比其大,则maxpos后移。
void SelectSort(int *array, size_t size)
{
    for (size_t i = 0; i < size-1; i++)//从第0个位置开始
    {
        size_t maxpos = i;
        for (size_t j = i+1; j < size ; j++)
        {
            if (array[j]<array[maxpos])
                maxpos = j;
        }
        if (maxpos != i)
        {
            swap(array[maxpos], array[i]);
        }
    }
}
int main()
{
    int array[] = { 8, 2, 6, 7, 9, 10 };
    int sz = sizeof(array) / sizeof(array[0]);
    Insert_BinarySearchSort(array, sz);
    for (int i = 0; i < sz; i++)
    {
        cout << array[i] << endl;
    }
    system("pause");
    return 0;
}

(2)、堆排序
a.创建堆:升序排序创建大堆,降序创建小堆。
b.循环执行的过程:1>将堆顶元素和当前堆的最后一个元素进行交换。
2>将堆的元素个数减1
3>向下进行调整。
代码实现如下:

void AdjustDown(int* array, size_t size, size_t parent)
{
    size_t child = parent * 2 + 1;
    while (child < size)
    {
        if (child + 1 < size&&array[child + 1] >array[child])
        {
            child+=1;
        }
        if (array[child]>array[parent])
        {
            std::swap(array[child], array[parent]);
            parent = child;
            child = parent * 2 + 1;
        }
        else
        {
            break;
        }
    }
}

void HeapSort(int* array, size_t size)
{
    建大堆  
    for (int i = (size - 2) / 2; i >= 0; --i)
    {
        AdjustDown(array, size, i);
    }
    int end = size - 1;
    while (end)
    {
        swap(array[0], array[end]);
        AdjustDown(array, end, 0);
        end--;
    }
}
int main()
{
    int array[] = { 10, 11, 12, 14, 12, 1, 2, 3, 4, 15, 19 };
    int len = sizeof(array) / sizeof(array[0]);
    HeapSort(array, len);
    for (size_t i = 0; i < len; ++i)
    {
        cout << array[i] << " ";
    }
    system("pause");
    return 0;
}

交换排序:
(1)、冒泡排序:较简单,不做详细说明。代码如下:

void BubbleSort(int *array, size_t size)
{
    for (int i = 0; i < size; i++)
    {
        bool exchange = false;
        for (int j = 0; j < size - i - 1; j++)
        {
            if (array[j]>array[j + 1])
            {
                swap(array[j], array[j + 1]);
                exchange = true;
            }
        }
    }
}
int main()
{
    int array[] = { 10, 11, 12, 14, 12, 1, 2, 3, 4, 15, 19 };
    int len = sizeof(array) / sizeof(array[0]);
    HeapSort(array, len);
    for (size_t i = 0; i < len; ++i)
    {
        cout << array[i] << " ";
    }
    system("pause");
    return 0;
}

(2)、快速排序:(一种二叉树结构的交换排序方法)
方法一:划分—>基准值—>左右两半部分。、
一趟排序如下:(这组数据代表性不强)
这里写图片描述

size_t postion1(int *array, size_t left, size_t right)
{
    size_t begin = 0;
    size_t end = right - 1;
    int key = array[end];
    while (begin < end)
    {
        while (begin < end&&array[begin]<=key)
        {
            begin++;
        }
        while (begin<end&&array[end]>=key)
        {
            end--;
        }
        if (begin < end)
        {
            swap(array[begin], array[end]);
        }
    }
    swap(array[begin], array[right-1]);//交换array[begin]与最后一个元素。
    return begin;//返回基准记录的位置
}
void quickSort(int *array, int left, int right)
{
    if (left < right)
    {
        int div = postion1(array, 0,right);
        quickSort(array, left, div);//左侧排序
        quickSort(array, div +1, right);//右侧排序
    }
}
int main()
{
    int array[] = { 10,11,5,9,8,6};
    int sz= sizeof(array) / sizeof(array[0]);
    quickSort(array,0,sz);
    for (size_t i = 0; i <sz; ++i)
    {
        cout << array[i] << " ";
    }
    system("pause");
    return 0;
}

(2)、挖坑法:
这里写图片描述
具体代码如下:

size_t postion2(int *array, size_t left,size_t right)//挖坑法
{
    size_t begin = left;
    size_t end = right - 1;
    int key = array[end];
    while (begin < end)
    {
        while (begin<end&&array[begin]<=key)
        {
            begin++;
        }
        if (begin < end)
        {
            array[end] = array[begin];
        }
        while (begin < end&&array[end] >= key)
        {
            end--;
        }
        if (begin < end)
        {
            array[begin] = array[end];
        }
    }
    array[begin] = key;
    return begin;
}
void quickSort(int *array, int left, int right)
{
    if (left < right)
    {
        int div = postion2(array, 0, right);
        quickSort(array, left, div);//左侧排序
        quickSort(array, div + 1, right);//右侧排序
    }
}
int main()
{
    int array[] = { 10, 11, 5, 9, 8, 6 };
    int sz = sizeof(array) / sizeof(array[0]);
    quickSort(array, 0, sz);
    for (size_t i = 0; i <sz; ++i)
    {
        cout << array[i] << " ";
    }
    system("pause");
    return 0;
}

归并排序:
具体步骤:1.将数据分为左右相等的两半部分。
2.再进行归并。
这里写图片描述
代码:

外部排序---归并排序
1.递归
void Merge(int *array, int left, int mid, int right, int*temp)
{
    int begin1 = left;
    int end1 = mid;
    int begin2 = mid;
    int end2 = right;
    int index = left;
    while (begin1 <end1&&begin2 < end2)
    {
        if (array[begin1] < array[begin2])
        {
            temp[index++] = array[begin1++];
        }
        else
        {
            temp[index++] = array[begin2++];
        }
    }
    while (begin1 < end1)
    {
        temp[index++] = array[begin1++];
    }
    while (begin2 < end2)
    {
        temp[index++] = array[begin2++];
    }
    将temp中的数据拷进arraymemcpy(array+left , temp+left , (right - left)*sizeof(int));//最后一个参数是字节个数
}
void MergeSort(int *array, int left, int right,int *temp)
{
    if (right - left <= 1)
    {
        return;
    }
    if (left < right)
    {
        int mid = left + ((right - left) >> 1);
        MergeSort(array, left, mid, temp);//左侧有序
        MergeSort(array, mid , right, temp);//右侧有序
        Merge(array, left, mid, right, temp);//再将两个有序序列合并
    }
}
int main()
{
        int array[] = { 2,0,4,9,3,6,8,7,1,5 };
        int sz = sizeof(array) / sizeof(array[0]);
        int *temp = new int[sz];
        MergeSort(array, 0, sz, temp);
        for (size_t i = 0; i <sz; ++i)
        {
            cout << array[i] << " ";
        }
        delete[] temp;
        system("pause");
        return 0;
}
//非递归版本:
void MergeSortNorR(int *array, int size,int*temp)
{
    int gap = 1;
    while (gap < size)//总的组数
    {
        for (int i = 0; i < size; i += 2 * gap)
        {
            int left = i;
            int mid =i+gap;
            int right = mid + gap;
            if (mid>size)
            {
                mid = size;
            }
            if (right > size)
            {
                right = size;
            }
            Merge(array, left, mid, right, temp);
        }
        gap = gap * 2;
    }
}
int main()
{
    int array[] = { 2,0,4,9,3,6,8,7,1,5};
    int sz = sizeof(array) / sizeof(array[0]);
    int *temp = new int[sz];
    MergeSortNorR(array, sz, temp);
    for (size_t i = 0; i <sz; ++i)
    {
        cout << array[i] << " ";
    }
    delete[] temp;
    system("pause");
    return 0;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值