排序(3)

七. 基数排序

规则:低位优先,所有数据从低位开始,依次放入到对应的十个桶内,再依次从桶中将数据取出

时间复杂度: O(n*log(2,n))

空间复杂度: O(n)

稳定性: 稳定

static int Get_Figure(int ar[], int len)//获取最大值的位数
{
    int max = ar[0];
    for (int i = 1; i < len; i++)
    {
        if (max < ar[i])
        {
            max = ar[i];
        }
    }
    int count = 0;
    while (max != 0)
    {
        count++;
        max /= 10;
    }
    return count;
}
static int Get_Num(int n, int fin)
{
    int  num = 0;
    while (fin != 0)
    {
        n = n / 10;
        fin--;
    }
    num = n % 10;
    return num;
}
static void Radix(int ar[], int len, int fin)//二维数组
{
    int bucket[10][20] = { 0 };//创建10个桶,每个桶有20个空间
    int num[10] = { 0 };//存放每个桶中存放的数据量
    for (int i = 0; i < len; i++)
    {
        int index = Get_Num(ar[i], fin);
        bucket[index][num[index]++] = ar[i];
    }
    //此时数据都以fin位依据,存放在桶中.
    int k = 0;
    for (int i = 0; i < 10; i++)//从桶内依次取值,放入数组中
    {
        for (int j = 0; j < num[i]; j++)
        {
            ar[k++] = bucket[i][j];
        }
    }

}
/*
static void Radix2(int ar[], int len, int fin)// 链式队列也ok
{
    LinkQueueHead quearr[10];
    for (int i = 0; i < 10; i++)
    {
        InitLinkQueue(&quearr[i]);
    }
    for (int i = 0; i < len; i++)
    {
        int index = Get_Num(ar[i], fin);
        Push(&quearr[index], ar[i]);
    }
    int k = 0;
    for (int i = 0; i < 10; i++)//从桶内依次取值,放入数组中
    {
        while (!IsEmpty(&quearr[i]))
        {
            Pop(&quearr[i], &ar[k]);
            k++;
        }
    }
    for (int i = 0; i < 10; i++)
    {
        Destory(&quearr[i]);
    }
}
*/
void RadixSort(int ar[], int len)
{
    assert(ar != NULL && len > 1);
    int count = Get_Figure(ar, len);
    for (int i = 0; i < count; i++)//循环次数
    {
        Radix2(ar, len, i);
    }
}

八. 快速排序:越有序,越慢.

规则: 选择一个基准值,以基准值为界限,左边的值大于基准值,右边的值大于基准值

1.从右向左找比基准值小的数,往前放

2.从左向右找比基准值大的数,往后放

3.重复1,2,直达left == right 将基准数放到ar[left]中

4.将所有基准数归位,则排序完成

时间复杂度: O(nlog(2,n))

空间复杂度: O(1)

稳定性: 不稳定

优化:

1. 如果有效数值较少,则选择直接插入排序
2. 对基准数的选:三数取中
3. 防止完全有序,自己打乱

static int onePaition(int ar[], int left, int right)//单向逼近
{
   int tmp = ar[left];
int i = left;
int j = left -1; //记录最后一个比tmp小的数的下标.
   for(; i<=right; i++)
{
// 4 5 6 3 2 1 7
if(ar[i] < tmp)
{
j++;
std::swap(ar[j],ar[i]);

           }

      }

      std::swap(ar[j],ar[left]);//将基准数归位.

      return j;

}

static
int Parition(int ar[], int left, int right)//将ar[left]作为基准数归位(双向逼近) { int tmp = ar[left]; while (left < right) { while (tmp < ar[right] && right > left) { right--; } if (right > left) ar[left] = ar[right]; while (tmp >= ar[left] && right > left) { left++; } if (right > left) ar[right] = ar[left]; } ar[right] = tmp; return left; } void Quick_Stack(int ar[], int left, int right) //用栈实现非递归的快排 { stack <int> st; if (left < right) { int midindex = Parition(ar, left, right); if (left < midindex - 1) { st.push(left); st.push(midindex -1); } if (midindex + 1 < right) { st.push(midindex + 1); st.push(right); } } while (!st.empty()) { int R = st.top(); st.pop(); int L = st.top(); st.pop(); int index = Parition(ar, L, R); if (L < index - 1) { st.push(L); st.push(index - 1); } if (index + 1 < R) { st.push(index + 1); st.push(R); } } } void QuickPass(int ar[], int left,int right)//递归实现 { if (left >= right) { return; } int p = Parition(ar, left, right); QuickPass(ar, left, p - 1); QuickPass(ar, p + 1, right); } void QuickSort(int ar[], int len) { assert(ar != NULL && len > 1); //QuickPass(ar,0, len - 1); Quick_Stack(ar, 0, len-1); }

总结:

//关于排序算法
//1.算法的描述 2.算法的实现 3.效率(时间复杂度,空间复杂度 以及稳定性) 
//   稳定性: 如果两个关键值A和A^相等,初始时A在A^前面,排序后仍然是这样,则称是稳定的
//
// 
// 目录:                    效率分析:                                           稳定性:  
// 1.冒泡排序(沉石排序)       时间复杂度 O(n^2)           空间复杂度 O(1)             稳定         
// 2.直接插入排序            时间复杂度 O(n^2)           空间复杂度 O(1)             稳定              
// 3.希尔排序                时间复杂度 O(n^1.3 - 1.5)   空间复杂度 O(1)            不稳定
// 4.二路归并排序            时间复杂度 O(n*log(n))      空间复杂度 O(n)             稳定
// 5.(简单)选择排序          时间复杂度O(n^2)            空间复杂度O(1)             不稳定
// 6.堆排序                 时间复杂度 O(n*log(2,n))    空间复杂度 O(1)            不稳定
// 7.基数(桶)排序            时间复杂度O(n)              空间复杂度O(n)              稳定           
// 8.快速排序               时间复杂度O(nlog(2,n))      空间复杂度O(1)             不稳定          

 

posted @ 2021-04-20 20:43  Wz_qq_2***6  阅读(34)  评论(0)    收藏  举报