数据结构 排序 插入排序

(1)直接插入

算法的复杂度O(n * n)。

头文件:

#define  MAXSIZE 20

#define  EQ(a, b) ((a) == (b))
#define  LT(a, b) ((a) < (b))
#define  LQ(a, b) ((a) <= (b))

typedef 
int  KeyType;

typedef 
int  InfoType;

typedef 
struct   {
    KeyType key;
    InfoType otherinfo;
}
RedType;

typedef 
struct   {
    
//r[0] is the sentinel, not used.
    RedType r[MAXSIZE + 1];
    
int length;
}
SqList;

源文件:

#include  " stdio.h "
#include 
" sort.h "

void  init(SqList  & s,  int  w[],  int  n) {
    s.length 
= n;
    
for(int i = 1; i <= n; i++){
        s.r[i].key 
= w[i - 1];
    }

}


void  show(SqList s) {
    
for(int i = 1; i <= s.length; i++){
        printf(
"%d ", s.r[i]);
    }

    printf(
" ");
}


void  insert(SqList  & s) {
    
for(int i = 2; i <= s.length; i++){
        
if(LT(s.r[i].key, s.r[i - 1].key)){
            
//set the sentinel
            s.r[0= s.r[i];
            s.r[i] 
= s.r[i - 1];
            
for(int j = i - 2; LT(s.r[0].key, s.r[j].key); j--){
                s.r[j 
+ 1= s.r[j];
            }

            s.r[j 
+ 1= s.r[0];
        }

    }

}


void  main() {
    
int w[] = {4938659776132749};
    
int n = 8;
    SqList s;
    init(s, w,  n);
    insert(s);
    show(s);
}

执行结果: 

13        27        38        49        49        65        76        97
Press any key to 
continue

(2)减少比较次数-折半插入

源文件添加:

// use the binary search method to find the location to insert.
void  binaryInsert(SqList  & s) {
    
for(int i = 2; i <= s.length; i++){
        
//set the sentinel
        s.r[0= s.r[i];
        
        
//binary search the location to insert
        int low = 1, high = i - 1;
        
int m;
        
while(low <= high){
            m 
= (low + high) / 2;
            
if(LT(s.r[0].key, s.r[m].key)){
                high 
= m - 1;
            }
else{
                low 
= m + 1;
            }

        }

        
        
for(int j = i - 1; j >= high + 1; j--){
            s.r[j 
+ 1= s.r[j];
        }

        s.r[high 
+ 1= s.r[0];
    }

}

折半插入仅减少了比较次数,而记录的移动次数没变。

(3)减少移动次数-表插入排序

头文件:

#define  SIZE 100

#define  EQ(a, b) ((a) == (b))
#define  LT(a, b) ((a) < (b))
#define  LQ(a, b) ((a) <= (b))

typedef 
int  KeyType;

typedef 
int  InfoType;

typedef 
struct   {
    KeyType key;
    InfoType otherinfo;
}
RedType;

typedef 
struct   {
    RedType rc;
    
int next;
}
SLNode;

typedef 
struct   {
    
//r[0] is head of static list
    SLNode r[SIZE];
    
int length;
}
SLinkListType;

源文件:

#include  " stdio.h "
#include 
" SLLInsert.h "

void  init(SLinkListType  & s,  int  w[],  int  n) {
    s.length 
= n;
    
for(int i = 1; i <= n; i++){
        s.r[i].rc.key 
= w[i - 1];
        
//point to the head, to use r[o] as a sentinal
        s.r[i].next = 0;
    }

    s.r[
0].next = 1;
}


void  show(SLinkListType s) {
    
for(int i = 0; i <= s.length; i++){
        printf(
"%d: %d(%d) ", i, s.r[i].rc.key, s.r[i].next);
    }

    printf(
" ");
}


void  insert(SLinkListType  & s) {
    
int parent, next;

    
for(int i = 2; i <= s.length; i++){
        
        s.r[
0].rc.key = s.r[i].rc.key;
        parent 
= 0;
        next 
= s.r[parent].next;

        
while(LT(s.r[next].rc.key, s.r[0].rc.key)){
            parent 
= next;
            next 
= s.r[next].next;
        }


        
//insert
        s.r[i].next = next;
        s.r[parent].next 
= i;
    }

}


void  main() {
    
int w[] = {4938659776132749};
    
int n = 8;
    SLinkListType s;
    init(s, w,  n);
    insert(s);
    show(s);
}

程序执行结果:

0 49 ( 6 )         1 49 ( 3 )         2 38 ( 8 )         3 65 ( 5 )         4 97 ( 0 )
5 76 ( 4 )         6 13 ( 7 )         7 27 ( 2 )         8 49 ( 1 )
Press any key to 
continue

表插入并没有减少比较次数,故复杂度仍为O(n * n)。

 (4)shell排序

子序列的构成不是简单的“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列。

源文件添加:

// one pass of shell sort
void  shellInsert(SqList  & s,  int  dk) {
    
int j;
    
for(int i = dk + 1; i <= s.length; i++){
        
if(LT(s.r[i].key, s.r[i - dk].key)){
            s.r[
0= s.r[i];
            
for(j = i - dk; j > 0 && LT(s.r[0].key, s.r[j].key); j -= dk){
                s.r[j 
+ dk] = s.r[j];
            }

            s.r[j 
+ dk] = s.r[0];
        }

    }

}


void  shellSort(SqList  & s,  int  dlta[],  int  t) {
    
for(int k = 0; k < t; k++){
        shellInsert(s, dlta[k]);
    }

}


void  main() {
    
int w[] = {4938659776132749};
    
int n = 8;

    
int dlta[] = {531};
    
int t = 3;

    SqList s;
    init(s, w,  n);
    
//binaryInsert(s);
    shellSort(s, dlta, t);

    show(s);
}

程序执行结果:

13        27        38        49        49        65        76        97
Press any key to 
continue

注意:增量序列中 dlta[] 没有除了1以外的公因子,并且最后一个增量值必须等于1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值