shell排序:
这个排序的命名是来自发明者的名字,和排序的方法没有字面上的联系。所以不要因为名字而感觉很难。在K&R的C程序设计语言中书中只用了几行代码很简洁的实现了这个排序算法。那就来看看这个排序是如何实现的。
原理:
我们将所要排序的序列(大小为n)划分成组,组的数量一般是可以用这个序列的大小的一半来定义(也就是d = n/2),然后不断折半,而组的成员就是间隔为d的数分为一组。比如这边有个长度为8的数字序列要去排序,那我们就可以先将这个序列分成d=4组的,每个组有两个数,(这边的4就是8的一半)。这四组就是(R1,R5),(R2,R6),(R3,R7),(R4,R8).然后就是组内比较,如果前者大,交换他们的位置。以次类推。编写程序时就是将我们所取的数和与他间隔为d大小的位置上的数比较。这边第一次组的数量是4,那么就是将第一个数和他间隔为4的数比较。当第一次排序后,我们将这个间隔缩小,就是拿上一次组数d折半。那么这次的组就只有2个了。每个组有4个数.同样是和上面一样,间隔为d=2的位置上的数比较(实际上操作是这样的,但是我们可以认为他们已经是在一个组里面了,就可以说成组内比较)。我们知道d最后会变成1的,那会儿就是相邻的两个数比较,所有的数字都会放在正确的位置上的。原理基本是这样的。
实现:
我们知道了原理,那就用自己熟悉的语言将其编写出来,我们这边是用的C语言,将其编写出来的。
我们按照我们上述的原理将其一步一步的实现下:
//函数的参数包含两个,一个是要排序的数组,一个是数组的大小
//函数不使用额外的空间,只用到数组本身。这就要求数组在输入时候保留出
//R[0],R[0]就相当是一个temp。用于互换两个数时的一个临时数。
void shellsort(int R[],int n)
{
int i,j,d;
d = n/;
while(d >= )
{
//注意i的起始和最后的那个“=,我们的第一个数是R[1],所以i-d要从1开始
for(i = d + ;i <= n;i++)
{
j = i - d;
//将R[i]暂存
R[] = R[i];
//这边的R[0]就是R[j+d]也就是R[i]
while(j> && R[j] > R[])
{
//将j位置的值给j+d位置
R[j+d] = R[j];
j -= d;
}
//这边就是对应着上面的j-=d,如果上面的while执行了,j
//位置的值已经给了j+d位置了,那么j+d的值也要给j位置,互换
//这就要求下标必须是对应的。所以要将j-d才能满足这边是R[j]
//如果while没有执行,那么还将原来的R[i]的值放到原来位置上
R[j+d] = R[];
}
//d减半
d/=;
}
}
上面就是按照所述的原理实现的,代码也不是很多,但是看上去有点乱,那么能不能改进点呢?下面就来了啊。
精简:
我们一般在保证程序的可读上,将程序变得很精巧。这也是K&R的一个思想把。我们知道while和for在一定的情况下是可以替代的。所以我们可以将上述的程序,变得更为紧凑些,我们用三个for循环就可以了。下面是精简后的实现:
#include<stdio.h> #define N 100
void shellsort(int *,int); int main(void)
{
int v[N];
int n,i; printf("输入你数组的大小:");
scanf("%d",&n); printf("输入%d个数,空格隔开:\n",n);
for(i = ;i < n; i++)
{
scanf("%d",&v[i]);
} shellsort(v,n); printf("shell排序后:");
for(i =;i < n;i++)
{
printf("%3d",v[i]);
} printf("\n");
return ;
} void shellsort(int v[],int n)
{
int i,j,temp,gap; for(gap = n/;gap > ;gap /=)
for(i =gap ;i < n ;i++)
for(j = i - gap;j>= && v[j] >v[j+gap]; j-=gap)
{
temp = v[j];
v[j] = v[j+gap];
v[j+gap] = temp;
}
}
这边我给出了一个完整的程序,不过我们只看函数的实现。上面的函数中,第一个for循环控制的是被比较数之间的间隔,也可以说是分组的依据。中间的循环是控制元素移动位置的。最后一个循环就是组内的比较,如果顺序不对就交换位置。将第一个函数里面的while整合成了for,这样看起来程序很精简,我们在理解上可能会有些卡壳,如果熟悉while和for之间转换的话就会好很多。
补充:
for(表达式1;表达式2;表达式3)
语句;
等价于while的为:
表达式1;
while(表达式2)
{
语句;
表达式3;
}
数据结构学习——shell排序的C语言实现的更多相关文章
-
数据结构之shell排序
#SIZE 10 //直接插入排序 void insert_sort(){ int i,j; int array[SIZE+1]; ...
-
c语言数据结构学习心得——排序
排序:将无序的序列重新排列为有序的序列. 插入类排序 插入类排序:在一个有序的序列中,插入一个新的关键字,知道所有的关键字都插入形成一个有序的序列. 直接插入排序:首先以一个元素为有序的序列,然后将后 ...
-
JS数据结构学习之排序
在看<>这本书中关于排序这一章的时候,我试着用javascript语言来重写里面几个经典的排序方法,包括冒泡排序.快速排序.选择排序.插入排序还有希尔排序. 一.冒泡排序 冒泡排序算是排序 ...
-
算法与数据结构之选择排序(C语言)
#include<stdio.h> #include<stdlib.h> void SelectSort(int *a,int n);//预声明要调用的函数 int main( ...
-
数据结构学习(shell排序和归并排序)
# coding=utf-8 # shell排序 # 参数alist:被被排序的列表 def shellsort(alist): gap = len(alist) / 2 while gap > ...
-
C / C++算法学习笔记(8)-SHELL排序
原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...
-
数据结构与算法之--高级排序:shell排序和快速排序
高级排序比简单排序要快的多,简单排序的时间复杂度是O(N^2),希尔(shell)排序大约是O(N*(logN)^2),而快速排序是O(N*logN). 说明:下面以int数组的从小到大排序为例. 希 ...
-
数据结构-排序-shell排序
shell排序 首先,希尔排序适用于待排序列关键有序. 接下来一步步图解SHELL排序 我为了方便理解内部操作.我先把代码输出整理下. #include<iostream> #includ ...
-
学习	shell脚本之前的基础知识
转载自:http://www.92csz.com/study/linux/12.htm 学习 shell脚本之前的基础知识 日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写sh ...
随机推荐
-
Spark MLlib之协同过滤
原文:http://blog.selfup.cn/1001.html 什么是协同过滤 协同过滤(Collaborative Filtering, 简称CF),wiki上的定义是:简单来说是利用某兴趣相 ...
-
LR 测试数据库总结
今天工作中需要对mysql进行性能测试 我尝试用LR来做:但是mysql需要现在电脑上安装一个OBDC的mysql驱动器,然后在电脑的管理工具中的数据源中加入这个mysql驱动,测试连接数据库成功,O ...
-
非常有用!eclipse与myeclipse恢复已删除的文件和代码
eclipse与myeclipse恢复已删除的文件和代码 今天写了1300多行代码,被不小心删除了顿时感觉手足无措,后来用myeclipse的历史文件恢复功能,找回来了,虚惊一场!!!MyEclip ...
-
Qt入门(20)——Qt模块简介
当你安装Qt时,这些模块会被构建到库中.在Qt企业版.Qt评估版和Qt*版中,包含所有的模块.对于Qt专业版,提供基本的模块--工具.核心.窗口部件.对话框.图标视图和工作区模块.画布模块画布模块提 ...
-
源代码解读Cas实现单点登出(single sign out)功能实现原理--转
关于Cas实现单点登入(single sing on)功能的文章在网上介绍的比较多,想必大家多多少少都已经有所了解,在此就不再做具体介绍.如果不清楚的,那只能等我把single sign on这块整理 ...
-
java web Servlet 学习笔记 -3 会话管理技术
Cookie和HttpSession 什么是会话: 用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 每个用户在使用浏览器与服务器进行会话的过 ...
-
JavaScript的Date类的函数特殊处理导致的问题
记得以前参加校招的时候,总是有日期相关的面试题,比如计算两个日期之间的间隔天数.以前还觉得这种题就是为了纯粹为了面试的,但工作了之后,还就碰到了跟日期相关的bug.下面是一段js代码,是要把字符串描述 ...
-
[深入理解Android卷一全文-第四章]深入理解zygote
由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的所有内容. ...
-
Supervisor安装与配置
Supervisor(http://supervisord.org/)是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统 ...
-
使用deque模块固定队列长度,用headq模块来查找最大或最小的N个元素以及实现一个优先级排序的队列
一. deque(双端队列) 1. 使用 deque(maxlen=N)会新建一个固定大小的队列.当新的元素加入并且这个队列已满的时候,最老的元素会自动被移除掉 >>> from c ...