shell排序
shell排序的基本定义
希尔排序(shell sort)是D.L.Shell于1959年提出的一种排序算法。
希尔排序:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<;…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
希尔排序采用跳跃分割的策略:将相聚某个“增量”的记录组成一个子序列,这样才能保证有序子序列分别进行直接插入排序的结果是基本有序而不是局部有序。
基本有序和局部有序
基本有序:若一个数据序列从小到大进行排序中,大的数据基本上在后面,小的数据基本上在前面,而不大不小的数据基本上在中间,则此数据序列可以被称为基本序列。
局部有序:将一个数据序列分割为多个部分,每个部分中的数据保持有序被称为局部有序
个人对shell排序的理解
希尔排序实质上是一种分组插入方法。
将数据序列按等间隔取值,例如:一个有九个数据的数据序列{0, 1, 5, 10, 9, 52, 20, 82, 4},将其按照n的间隔进行两两的排序最后成为一个基本序列。
最后将其的间隔缩小重复上述步骤直至间隔缩小为一,也即增量为1结束
希尔排序实现的几种方式
1.最初的希尔排序
/*
*D.Shell最初的算法。
*/
int shellsortSh(int p[],int n)
{
int op=0;
int h,i,j,temp;
for(h=n/2;h>0;h=h/2){
for(i=h;i<n;i++){
temp=p[i];
for(j=i-h;j>=0&&p[j]>temp;j-=h){
p[j+h]=p[j];
op++;
}
p[j+h]=temp;
op++;
}
}
return op;
}
shell排序算法C语言实现
void shellsort(int v[], int n){
int gap, i, j, temp;
for (gap = n / 2; gap > 0; gap /= 2){
for (i = gap; i < n; i++){
for (j = i - gap; j >= 0 && v[j]>v[j + gap];j-=gap){
temp = v[j];
v[j] = v[j + gap];
v[j + gap] = temp;
}
}
}
}
2.Lazarus-Frank 算法
/*
*原为在必要时加1使所有增量都为奇数,现修正为减1。
*/
int shellsortLF(int p[],int n)
{
int op=0;
int h,i,j,temp;
for(h=n/2;h>0;h=h/2){
if(h%2==0)
h--;
for(i=h;i<n;i++){
temp=p[i];
for(j=i-h;j>=0&&p[j]>temp;j-=h){
p[j+h]=p[j];
op++;
}
p[j+h]=temp;
op++;
}
}
return op;
}
引用于百度文库:链接: link
个人对shell的尝试
1.创建表
sqlist.h
#ifndef _SQLIST_H
#define _SQLIST_H
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAXSIZE 100
typedef int data_t;
typedef struct
{
data_t data[MAXSIZE];
int last;
}sqlist_t;
sqlist_t *sqlist_create();
void sqlist_init(sqlist_t **L);
int is_full(sqlist *L)
int get_len(sqlist_t *L);
void sqlist_show(sqlist *L);
void sqlist_clear(sqlist *L);
#endif
sqlist.c
#include "sqlist.h"
sqlist_t *sqlist_create()
{
sqlist_t *list=(sqlist_t *)malloc(sizeof(sqlist_t));
if(list==NULL)
{
perror("malloc");
return NULL;
}
list->last=-1;
return list;
}
void sqlist_init(sqlist_t **L)
{
*L=(sqlist_t *)malloc(sizeof(sqlist_t));
if(*L==NULL)
{
perror("malloc");
return ;
}
(*L)->last=-1;
}
void sqlist_clear(sqlist_t *L)
{
if(L==NULL)
{
printf("list no exist!\n");
return ;
}
free(L);
}
int get_len(sqlist_t *L)
{
if(L==NULL)
{
printf("list no exist!\n");
return -1;
}
return L->last+1;
}
void sqlist_show(sqlist_t *L)
{
if(L==NULL)
{
printf("list no exist!\n");
return ;
}
for(int i=0;i<L->last+1;i++)
{
printf("L->data[%d]: %d\n",i,L->data[i]);
}
printf("----------------\n");
}
int is_full(sqlist_t *L)
{
if(L==NULL)
{
printf("list no exist!\n");
return -1;
}
return (L->last==MAXSIZE-1);
}
int sqlist_insert(sqlist_t *L, data_t x, int pos)
{
if(L==NULL)
{
printf("list no exist!\n");
return -1;
}
if(is_full(L) || pos < 0 || pos > (L->last+1))
{
printf("sqlist can not insert\n");
return -1;
}
for(int i=L->last;i>=pos;i--)
{
L->data[i+1]=L->data[i];
}
L->data[pos]=x;
L->last+=1;
return 0;
}
主函数
#include "sqlist.h"
void shellsort(sqlist_t *L)
{
int i,j;
int increment=L->last+1;
do
{
//每轮比较间隔,也叫增量序列
increment=increment/3+1;
for(i=increment;i<=L->last;i++)
{
if(L->data[i]<L->data[i-increment])
{
//将data[i]的位置空出来,将值暂存在temp中
int temp=L->data[i];
for(j=i-increment;j>=0&&L->data[j]>temp;j-=increment)
{
L->data[j+increment]=L->data[j];
}
L->data[j+increment]=temp;
}
}
}while(increment>1);
return ;
}
int main(int argc, char *argv[])
{
srand(time(NULL));
sqlist_t *L = NULL;
sqlist_init(&L);
if(is_full(L) == 1)
printf("full!\n");
else
printf("no full!\n");
int i=0,ra=0;
while(i < 10){
sqlist_insert(L,(ra=rand()%20) , i);
i++;
}
sqlist_show(L);
shellsort(L);
sqlist_show(L);
sqlist_clear(L);
return 0;
}