*排序综合*

1. 快速排序

void qsort(int low, int high, int a[])
    {
        int x = a[low];
        int i = low, j = high;
        if(low>=high)
            return;
        while(i<j)
        {
            while(i<j&&a[j]>=x)
                j--;
            a[i] = a[j];
            while(i<j&&a[i]<=x)
                i++;
            a[j] = a[i];
        }
        a[i] = x;
        qsort(low, i-1, a);
        qsort(i+1, high, a);
    }



2.归并排序

归并排序其实要做两件事:
(1)“分解”——将序列每次折半划分。
(2)“合并”——将划分后的序列段两两合并后排序。



void Merge(int a[], int low, int mid, int high)
{
    int i = low;//第一段序列的下标
    int j = mid + 1;//第二段序列的下标
    int k = 0;//暂存数组的下标
    int *b = (int *)malloc((high - low + 1)*sizeof(int));//暂存数组动态分配内存
    while(i<=mid&&j<=high)// 判断第一段和第二段取出的数哪个更小,将其存入合并序列,并继续向下遍历
    {
        if(a[i]<a[j])
            b[k++] = a[i++];
        else
            b[k++] = a[j++];
    }
    while(i<=mid)// 若第一段序列还没遍历完,将其剩余全部复制到合并序列
        b[k++] = a[i++];
    while(j<=high)// 若第二段序列还没遍历完,将其剩余全部复制到合并序列
        b[k++] = a[j++];
    
    for(k=0, i=low; i<=high; i++, k++)// 将合并序列复制到原始序列中
        a[i] = b[k];
}


void mergesort(int a[], int low, int high)
{
    int mid;
    if(low<high)
    {
        mid = (low + high)/2;
        mergesort(a, low, mid); //递归划分并归并
        mergesort(a, mid+1, high);
        Merge(a, low, mid, high);   
    }
    
}


3. 希尔排序:将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序;

然后再选择一个更小的增量,再将数组分割为多个子序列进行排序,最后选择增量为1,即使用直接插入排序,使最终数组成为有序数组。


void shellsort(int a[], int n)
{
    int i, j, d, t;
    for(d = n/2; d>0; d/=2)
        for(i = d; i<n; i++)
            for(j = i-d; j>=0; j-=d)
            {
                if(a[j]>a[j+d])
                {
                    t = a[j];
                    a[j] = a[j+d];
                    a[j+d] = t;
                }
            }
}

4. 堆排序

筛选:
(1). 根节点与最后一个节点元素交换;
(2). 左右子树比较选择较大者与堆顶记录数比较,取最大值置于根节点;
(3). 依次遍历改变后的子树的结点,将左右子树较大者与堆顶记录数进行比较, 取最大值置于结点处;
建堆:
(1).  建大顶堆,从最后一个有子树的结点起逐渐向上调整;
(2). 依次进行筛选直到堆顶记录数取遍所有元素;


void HeapAdjust (int a[], int s, int m) //筛选
{
    int j;
    int rc=a[s];//根节点(堆顶记录数)
    for (j=2*s; j<=m; j*=2)//从每个节点的左子树开始遍历
    {
        if (j<m&&a[j]<a[j+1]) //比较左右子树取较大值
            ++j;
        if (rc>a[j]) //若当前节点大于其左右子树则无需交换
            break;
        a[s] = a[j];
        s=j;
    }
    a[s] = rc; //将堆顶记录数存到最后一个比较的位置
} // HeapAdjust

void HeapSort (int a[])
{
    int i, t;
    for (i=n/2; i>0; --i) //建大顶堆,从最后一个有子树的节点起逐渐向上调整
        HeapAdjust (a, i, n);
    printf("%d", a[1]);
    for (i=n; i>1; --i) //依次进行筛选
    {
        t = a[1];
        a[1] = a[i];
        a[i] = t;    //将堆顶元素与当前未经排序的序列的最后一个元素进行交换
        HeapAdjust (a, 1, i-1);
        printf(" %d", a[1]);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值