关于shell排序

今天看了C++之父写的C++程序设计,对于其中的shell排序有了一个比较好的认识,记录下来以便日后复习

shell排序用到了分组和插入排序的方法

例如有个数组{5, 6, 3,2,1, 4}

首先先分组,以数组的长度n / 2 = 3

这样就分为了{5,2} {6,1} {3,4}  注意每组的元素为数组元素每间隔n/2个元素之后的那个元素  比如5, 之后应该是2,依次类推

然后每组进行插入排序得到{2, 5}  {1, 6} {3,4}

注意代码所体现的插入排序的顺序是:如果每组是{5, 3, 2}  {6, 1, 4}  {3, 4, 5} 那么他会先以3进行插入之后 会跳到第二组以1进行第二组的插入,之后是第三组  然后在返回第一组以2进行插入依次类推


然后3/2=1 这样就分为了1组也就是全部{2,5,1, 6, 3, 4}进行插入排序最后得到{1, 2, 3, 4, 5, 6}


以C++之父所写的运用代码

int cmp1(void *, void *);
int cmp2(void *, void *);

//shell排序的运用
typedef int (*CFT)(const void *, const void *);

void ssort(void *base, size_t n, size_t sz, CFT cmp)
{
    /*对向量base的n个元素进行递增排序
      用由‘cmp’所指的函数进行比较
      元素的大小为sz
     */

    for (int grap = n / 2; grap > 0; grap /= 2)
    {
        for (int i = grap; i < n; i++)
        {
            for (int j = i - grap; j >= 0; j -= grap)
            {
                char *b = static_cast<char *>(base);
                char *pj = b + j * sz;
                char *pjg = pj + grap * sz;

                if (cmp(pjg, pj) < 0)
                {
                    for (int k = 0; k < sz; k++)
                    {
                        char temp = pj[k];
                        pj[k] = pjg[k];
                        pjg[k] = temp;
                    }
                }
            }
        }
    }
}

struct User {
    char *name;
    char *id;
    int dept;
};

User heads[] = {
    "Ritchie D.M.",   "dmr",   11271,
    "Sethi R.",         "ravi",  11272,
    "Szymanski T.G.", "tgs",   11273,
    "Schryer N.L.",      "nls",   11274,
    "Scheyer N.L.",   "nls",   11275,
    "Kernigham B.W.", "bwk",   11276
};

void print_id(User *v, int n)
{
    for (int i = 0; i < n; i++)
        cout << v[i].name << '\t' << v[i].id << '\t' << v[i].dept << '\n';
}

int cmp1(const void *p, const void *q) //比较名字字串
{
    return strcmp(static_cast<const User*>(p)->name,
                            static_cast<const User*>(q)->name);
}

int cmp2(const void *p, const void *q) //比较部门
{
    return static_cast<const User*>(p)->dept -
                            static_cast<const User*>(q)->dept;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值