7-冒泡排序&选择排序

十大排序算法详解

冒泡排序

冒泡排序:挨个挨个去比较
时间复杂度:O(n^2)
空间复杂度:O(1)
算法稳定性:稳定
原理:
从数组的第一个位置开始两两比较arr[j]和arr[j+1],
如果arr[j]大于arr[j+1]则交换他两个的位置,直到数组结束;
从数组的第一个位置开始,重复上面的动作,止到数组长度减一个位置结束;
从数组的第一个位置开始,重复上面的动作,止到数组长度减二个位置结束;
例:4 1 5 12 0
第一趟:1 4 5 0 12 i=0 j<4
第二趟:1 4 0 5 12 i=1 j<3
第三趟:1 0 4 5 12 i=2 j<2
第四趟:0 1 4 5 12 i=3 j<1
在这里插入图片描述

void Bubble_Sort(int *arr, int len)//下沉{    int i, j;    int tmp=0;    bool swap = false;    for (i = 0; i < len - 1; i++)    {        swap = false;        for (j = 0; j < len - 1 - i; j++)        {            if (arr[j] > arr[j + 1])            {                tmp = arr[j];                arr[j] = arr[j + 1];                arr[j + 1] = tmp;                swap = true;            }        }        if (!swap)//swap==false没有交换        {            return;        }    }}void Bubble_Sort1(int *arr, int len)//上浮{    int i;    int j;    int tmp;    bool swap=false;    for (i = 0; i < len; i++)    {        swap = false;        for (j = i + 1; j < len; j++)        {            if (arr[i] > arr[j])            {                tmp = arr[i];                arr[i] = arr[j];                arr[j] = tmp;                swap=true;            }        }        if(!swap)        {            return;        }    }}void Bubble_Sort2(int *arr, int len)//不开辟tmp{    int i, j;    for (i = 0; i<len - 1; i++) //扫描次数len-1       {        for (j = len - 1; j>i; j--)        {            if (arr[j] > arr[j - 1])            {                arr[j] += arr[j - 1];                arr[j - 1] = arr[j] - arr[j - 1];                arr[j] = arr[j] - arr[j - 1];            }        }    }}




void Swap(int *a, int *b)
{
    int c = *a;
    *a = *b;
    *b = c;
}


//O(n^2)    O(1)      稳定
void BubbleSort(int *arr, int len)
{
    for (int j = 0; j < len - 1; ++j)  
    {
        int flag = 0;
        for (int i = 0; i < len - j - 1; ++i)
        {
            if (arr[i] > arr[i + 1])
            {
                Swap(&arr[i], &arr[i + 1]);
                flag = 1;
            }
        }


        if (!flag)
        {
            break;
        }
    }
}

直接选择排序的基本思想

n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。

  • 第1趟从R[0]~R[n-1]中选取最小值,与R[0]交换;
  • 第2趟从R[1]~R[n-1]中选取最小值,与R[1]交换;
  • 第i趟从R[i-1]~R[n-1]中选取最小值,与R[i-1]交换;

直接选择排序和直接插入排序类似,都将数据分为有序区和无序区,所不同的是直接插入排序是将无序区的第一个元素直接插入到有序区以形成一个更大的有序区,而直接选择排序是从无序区选择一个最小的元素直接放到有序区的最后。
直接选择排序算法的核心

确定待排序的数据R[0…n]
确定需比较的数据R[i…n]
每次找出最小值,进行交换

直接选择排序算法的示例
给定一组数据[8 3 2 5]
第一次交换 8<->2
2 3 8 5
第二次交换 3<->3
2 3 8 5
第三次交换 8<->5
2 3 5 8
程序1

// O(n^2)   O(1)   不稳定
void SelectSort(int *arr, int len)
{
    for (int i = 0; i < len - 1; ++i)
    {
        int min = i;
        for (int j = i + 1; j < len; ++j)
        {
            if (arr[j] < arr[min])
            {
                min = j;
            }
        }


        if (min != i)
        {
            Swap(&arr[i], &arr[min]);
        }
    }
}

程序2

void SelectSort(int *arr, int len)
{
   int i,j;           // 为循环做准
   int iMin;          // 存储每次最小值
   int temp;          // 作为临时存储值
   for (i=0; i<len-1; i++)         // 进行len-1趟比较即可
   {
           iMin = i;                               // 存储每次最小值
           for (j=i+1; j<len; j++) // 第i次需要与之比较的数据
           {
                   if (arr[iMin]>arr[j])
                   {
                           iMin = j;               // 记录最小值的位置
                   }
           }
           temp = arr[i];                  // 交换
           arr[i] = arr[iMin];
           arr[iMin] = temp;
   }
}

带注释的完整各个排序:(包括插入选择冒泡等)

void Show(int *arr, int len)
{
    for (int i = 0; i < len; ++i)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}
void Swap(int *bp, int *ap)
{
    int tmp = *bp;
    *bp = *ap;
    *ap = tmp;
}
//冒泡排序法
void BobbleSort(int *arr, int len)
{
    for (int j = 0; j < len - 1; j++)
    {
        int flag = 1;//原本有序情况
        for (int i = 0; i < len -j- 1; i++)
        {
            if(arr[i]>arr[i+1])
            {
            Swap(&arr[i], &arr[i + 1]);
            }
            flag = 0;
        }
        if (flag)
        {
           break;
        }
    }
}
//选择排序法
//o(n^2) o(1) 如果产生跳跃式的交换则不稳定
void SelectSort(int *arr, int len)
{
    for (int i = 0; i < len - 1; ++i)
    {
        int min = i;
        for (int j = i + 1; j < len; ++j)
        {
        
        if (arr[j] < arr[min])
        {
            min = j;
        }
        }
    
        if (min!= i)
         {
           Swap(&arr[i], &arr[min]);
         }       
    }
    
}
//插入排序法
//时间复杂度o(n^2)  空间复杂度o(1)  稳定  数据越有序,效率越高
void InsertSort(int *arr, int len)
{
    for (int i = 1; i < len;++i)
    {
        int tmp = arr[i];
        int j = 0;
        for (j = i - 1; j >= 0 && arr[j] > tmp; j--)
        {
            arr[j + 1] = arr[j];
        }
        arr[j + 1] = tmp;
    }
}
void InsertSort2(int *arr, int len)
{
    int i = 1;
    int j = 0;
    int tmp = 0;
    while (i < len)
    {
        tmp = arr[i];
        j = i - 1;
        while (j >= 0 && arr[j]>tmp)
        {
            arr[j + 1] = arr[j];
        }
        arr[j + 1] = tmp;
    }
}
//希尔排序 分组排序----数据趋近于有序
void Shell(int *arr, int len, int t)
{
    int i = t;
    int j = 0;
    int tmp = 0;
    while (i < len)
    {
        tmp = arr[i];
        j = i - t;
        while (j >= 0 && arr[j]>tmp)
        {
            arr[j + t] = arr[j];
        }
        arr[j + t] = tmp;
    }
}
//希尔排序 分组排序----数据趋近于有序
//o(n^1.3--n^1.5)  o(1) 不稳定
void ShellSort(int *arr, int len)
{
    int d[] = { 7,5,3,1 };
    for (int i = 0; i < sizeof(d) / sizeof(d[0]); i++)
    {
        Shell(arr, len, d[i]);
    }
}
int main()
{
    int arr[] = { 12,34,23,45,78,67,90,89,56 };
    int len = sizeof(arr) / sizeof(arr[0]);
    Show(arr, len);
    //BobbleSort(arr, len);
    //SelectSort(arr, len);
    //InsertSort(arr, len);
    //InsertSort2(arr, len);
    ShellSort(arr, len);
    Show(arr,len);
    return 0;
}
发布了82 篇原创文章 · 获赞 7 · 访问量 4196

猜你喜欢

转载自blog.csdn.net/sunshine612/article/details/104701477