八种排序

 八大排序

1. 冒泡排序

void BulleSort(int a[], int len) // 冒泡排序
{
    int i, j, temp;
    for(i = 0; i < len; i++)
    {
        for(j = len - 1; j > i; --j) // 每次循环一次都找到最小大的值,循环次数减1
        {
            if(a[j] < a[j - 1])
            {
                temp = a[j];
                a[j] = a[j - 1];
                a[j - 1] = temp;
            }
         }
     }
}

2.快速排序

// 快速排序
void QuickSort(int a[], int L, int H)  // 第一次调用 QuickSort(a, 0, length - 1)
{
    int i, j;
    int index;

    if(L >= H) // 结束条件
    {
        return;
    }

    i = L;
    j = H;
    index = a[i];
// 挖坑填充法
    while(i < j) // 分成两部分
    {
        while(i < j && index <= a[j])  // 后半部分
        {
            j--;
        }
        if(i < j)
        {
            a[i++] = a[j];
        }

        while(i < j && index > a[i]) // 前半部分
        {
            i++;
        }
        if(i < j)
        {
            a[j--] = a[i];
        }
    }
// 方法2 
    int t;
    while(i < j) // 分成两部分
    {
        while(i < j && index <= a[j])  // 后半部分
        {
            j--;
        }

        while(i < j && index > a[i]) // 前半部分
        {
            i++;
        }
        if(i < j)
        {
            t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
    }
    a[left]=a[i];  
/****************/

    a[i] = index;
    QuickSort(a, L, i - 1);
    QuickSort(a, i + 1, H);
}

 3. 直接插入排序 

void InsertSort(int a[], int a_size) // 插入排序
{
    int i, j;
    int temp;

    for (i = 1; i < a_size; i++)
    {
        temp = a[i];
        for(j = i - 1; j >= 0; j--)  // 每次找得到本次循环中最小的将它放到开头
        {
            if(temp < a[j])
            {
                a[j + 1] = a[j];
            }
            else
            {
                break;
            }
        }
        a[j + 1] = temp;
    }
}

 4.希尔排序

void ShellSort(int a[], int len)  //  希尔排序
{
    int i, j;
    int h, temp;

    for (h = len / 2; h > 0; h = h / 2) // 分系列
    {
        for (i = h; i < len; i++) // 直接插入排序,步长为h
        {
            temp = a[i];
            for(j = i - h; j >= 0; j -= h)
            {
                if(temp < a[j])
                {
                    a[j + h] = a[j];
                }
                else
                {
                    break;
                }
            }
            a[j + h] = temp;
        }
    }
}

  5.基数排序 

void RadixCountSort(int *r, int *a, int len)
{
    int i;
    int *count = (int *)malloc(sizeof(int) * len);

    for(i = 0; i < len; i++) // 所有置为零
    {
        count[i] = 0;
    }

    for(i = 0; i < 10; i++) // 确定每个桶中的数量,桶的编号在 0~9之间
    {
        ++count[r[i]];
    }
    
    for(i = 1; i < len; i++) // 统计总数量
    {
        count[i] += count[i - 1];
    }

    int *sort = (int *)malloc(sizeof(int) * len);
    
    for( i = len - 1; i >= 0; i--)
    {
        --count[r[i]]; // 使用一次数量减一
        sort[count[r[i]]] = a[i]; 
    }

    for(i = 0; i < len; i++)
    {
        a[i] = sort[i];
    }

    free(sort); // 防止内存泄漏
    free(count);
    sort = count = NULL;  // 指针指向的内存已经无效了,而指针没有被置空,引用一个非空的无效指针是一个未被定义的行为,也就是说不一定导致段错误,野指针很难定位到是哪里出现的问题,在哪里这个指针就失效了,不好查找出错的原因,所以调试起来会很麻烦。
}

void RadixSort(int *a, int len) // 基数排序
{
    int i, ok = 0;
    int radix_base = 1;

    int *radix = (int *)malloc(sizeof(int) * len);

    while(!ok)
    {
        ok = 1;
        radix_base *= 10;

        for(i = 0; i < len; i++)  // 将各个位求出来便于分桶
        {
            radix[i] = a[i] % radix_base;
            radix[i] /= radix_base / 10;
            if(a[i] / (radix_base / 10) > 0)
            {
                ok = 0;
            }
        }
        if(ok)
        {
            break;
        }

        RadixCountSort(radix, a, len);
    }
    free(radix);  // 释放内存
    radix = NULL; // 防止成为野指针
}

 6.简单选择排序

void SelectSort(int a[], int len)  // 简单选择排序
{
    int i, j;
    int temp = 0, flag = 0;
    for(i = 0; i < len; i++)
    {
        temp = a[i];  // 当作最小值
        flag = i;
        for(j = i + 1; j < len; j++)
        {
            if(a[j] < temp)
            {
                flag = j;
                temp = a[j];
            }
        }
        if(flag != i)  // 不是最大值,替换为最大值
        {
            a[flag] = a[i];
            a[i] = temp;
        }
    }
}

 7.堆排序

 void AdjustMinHeap(int *a, int p, int len)
{
    int temp;
    int child;
    
    for(temp = a[p]; 2 * p + 1 <= len; p = child)
    {
        child = 2 * p + 1;
        if(child < len && a[child] > a[child + 1])
        {
            child++;
        }
        if(a[child] < temp)
        {
            a[p] = a[child];
        }
        else
        {
            break;
        }
    }
    a[p] = temp;
}

void HeapSort(int a[], int len) // 堆排序
{
    int i;
    int temp;

    for(i = len / 2 - 1; i >= 0; i--) // 改成为小顶堆
    {
        AdjustMinHeap(a, i, len - 1);
    }

    for(i = len - 1; i>= 0; i--)
    {
        temp = a[0]; // 将最小值放在最后 
        a[0] = a[i];
        a[i] = temp;

        AdjustMinHeap(a, 0, i - 1);// 堆中已经没有前一次找到的最小值,再次改造小顶堆,然后再一次去除最小的值
    }
}

 8.归并排序

void Merge(int a[], int l, int mid, int h)  // 并拢
{
    int i, j, k, n1, n2;

    n1 = mid - l + 1;
    n2 = h - mid ;

    int *L = (int *)malloc(sizeof(int));
    int *R = (int *)malloc(sizeof(int));

    for(i = 0, k = l; i < n1; i++, k++)
    {
        L[i] = a[k];
    }
    
    for(i = 0, k = mid + 1; i < n2; i++, k++)
    {
        R[i] = a[k];
    }

    for(k = l, i = 0, j = 0; i < n1 && j < n2; k++) // 合并
    {
        if(L[i] < R[j])
        {
            a[k] = L[i];
            i++;
        }
        else
        {
            a[k] = R[j];
            j++;
        }
    }
    // 可能其中一方数量多
    if(i < n1) // 
    {
        for(j = i; j < n1; j++, k++)
        {
            a[k] = L[j];
        }
    }

    if(j < n2) 
    {
        for(i = j; i < n2; i++, k++)
        {
            a[k] = R[i];
        }
    }

}

void MergeSort(int a[], int l, int h) // 归并排序
{
    int middle;
    int i;

    if(l < h)
    {
        middle = (l + h) / 2;
        // 不断分成两半
        MergeSort(a, l, middle);      // 前半部分
        MergeSort(a, middle + 1, h);  // 后半部分
        // 将分开的再合起来
        Merge(a, l, middle, h); 
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值