数据结构初学--关于SHELL排序的一些思考

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;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值