直接插入排序、折半插入排序、2_路插入排序

// c1.h (程序名)
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream> // cout,cin
using namespace std;
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
// #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE

 

 

// c10-1.h 待排记录的数据类型
#define MAX_SIZE 20 // 一个用作示例的小顺序表的最大长度
typedef int KeyType; // 定义关键字类型为整型
struct RedType // 记录类型
{
 KeyType key; // 关键字项
 InfoType otherinfo; // 其它数据项,具体类型在主程中定义
};
struct SqList // 顺序表类型
{
 RedType r[MAX_SIZE+1]; // r[0]闲置或用作哨兵单元
 int length; // 顺序表长度
};

 

 

// bo10-1.h 顺序表插入排序的函数(3个),包括算法10.1、10.2
// 对顺序表L作直接插入排序。算法10.1
void InsertSort(SqList &L)
{
 int i,j;
 for(i=2;i<=L.length;++i)
  if LT(L.r[i].key,L.r[i-1].key) // "<",需将L.r[i]插入有序子表L.r[i]<L.r[i-1];
  {
   L.r[0]=L.r[i]; // 复制为哨兵
   for(j=i-1;LT(L.r[0].key,L.r[j].key);--j)
    L.r[j+1]=L.r[j]; // 记录后移L.r[i]=L.r[i-1]
   L.r[j+1]=L.r[0]; // 插入到正确位置L.r[i]=L.r[0]
  }
}
// 对顺序表L作折半插入排序。算法10.2
void BInsertSort(SqList &L)
{
 int i,j,m,low,high;
 for(i=2;i<=L.length;++i)
 {
  L.r[0]=L.r[i]; // 将L.r[i]暂存到L.r[0]
  low=1;
  high=i-1;
  while(low<=high)
  { // 在r[low..high]中折半查找有序插入的位置
   m=(low+high)/2; // 折半
   if LT(L.r[0].key,L.r[m].key)
    high=m-1; // 插入点在低半区
   else
    low=m+1; // 插入点在高半区
  }
  for(j=i-1;j>=high+1;--j)
   L.r[j+1]=L.r[j]; // 记录后移
  L.r[high+1]=L.r[0]; // 插入
 }
}

void P2_InsertSort(SqList &L)
{ // 2_路插入排序
 int i,j,first,final;
 RedType *d;
 d=(RedType*)malloc(L.length*sizeof(RedType)); // 生成L.length个记录的临时空间
 d[0]=L.r[1]; // 设L的第1个记录为d中排好序的记录(在位置[0])
 first=final=0; // first、final分别指示d中排好序的记录的第1个和最后1个记录的位置
 for(i=2;i<=L.length;++i) // 依次将L的第2个~最后1个记录插入d中
  if(L.r[i].key<d[first].key)
  { // 待插记录小于d中最小值,插到d[first]之前(不需移动d数组的元素)
   first=(first-1+L.length)%L.length; // 设d为循环向量
   cout<<first<<endl;
   d[first]=L.r[i];
  }
  else if(L.r[i].key>d[final].key)
  { // 待插记录大于d中最大值,插到d[final]之后(不需移动d数组的元素)
   final=final+1;
   d[final]=L.r[i];
  }
  else
  { // 待插记录大于d中最小值,小于d中最大值,插到d的中间(需要移动d数组的元素)
   j=final++; // 移动d的尾部元素以便按序插入记录
   while(L.r[i].key<d[j].key)
   {
    d[(j+1)%L.length]=d[j];
    j=(j-1+L.length)%L.length;
   }
   d[j+1]=L.r[i];
  }
  for(i=1;i<=L.length;i++) // 把d赋给L.r
   L.r[i]=d[(i+first-1)%L.length]; // 线性关系
}

 

 

// c9-7.h 对两个数值型关键字的比较约定为如下的宏定义
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))

 

// algo10-1.cpp 检验bo10-1.h的程序
#include"c1.h"
typedef int InfoType; // 定义其它数据项的类型
#include"c9-7.h"
#include"c10-1.h"
#include"bo10-1.h"
void print(SqList L)
{
 int i;
 for(i=1;i<=L.length;i++)
  printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);
 printf("/n");
}

#define N 8
void main()
{
 SqList l1,l2,l3;
 RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
 int i;
 for(i=0;i<N;i++) // 给l1.r赋值
  l1.r[i+1]=d[i];
 l1.length=N;
 l2=l3=l1; // 复制顺序表l2、l3与l1相同
 printf("排序前:/n");
 print(l1);
 InsertSort(l1);
 printf("直接插入排序后:/n");
 print(l1);
 BInsertSort(l2);
 printf("折半插入排序后:/n");
 print(l2);
 P2_InsertSort(l3);
 printf("2_路插入排序后:/n");
 print(l3);
}

 

 

 

 

 

 

排序前:
(49,1)(38,2)(65,3)(97,4)(76,5)(13,6)(27,7)(49,8)
排序后:
(13,6)(27,7)(38,2)(49,1)(49,8)(65,3)(76,5)(97,4)

以下三种排序均为稳定排序


直接插入排序:
[初始关键字]:  (49) 38  65 97 76 13 27 49
i=2:   (38) (38  49) 65 97 76 13 27 49
i=3:   (65) (38  49  65) 97 76 13 27 49
i=4:   (97) (38  49  65 97) 76 13 27 49
i=5:   (76) (38  49  65 76 97) 13 27 49
i=6:   (13) (13  38  49 65 76 97) 27 49
i=7:   (27) (13  27  38 49 65 76  97) 49
i=8:   (49) (13  27  38 49 49 65 76 97
0(n^2)

折半插入排序:
[初始关键字]: (49) 38 65 97 76 13 27 49
i=2:  (38)(38 49)
i=3:  (65)(38 49)
                 low  high
                  m 
                         low
                          m
                                   low
              (65)(38 49 65)
i=4:        (97)(38  49 65)
                      low     high
                             m
                                 low
                                  m
                                      low
               (97)(38  49 65 97)
i=5:         (76)(38  49 65 97)
                       low           high
                              m
                                  low
                                   m
                                        low
                                          m
                                  high
                                  L.r[5]=L.r[4]即把76换成97
                                  L.r[4]=L.r[0]即把76插入L.r[4]中
                  (76)(38  49 65 76 97)     
i=6:            (13)(38  49 65 76 97)
                          low                high
                                      m
                               high
                           m
                          high
                            m
                  high
                   (13)(13  38 49 65 76 97)
i=7:             (27)(13  38 49 65 76 97)
                           low                     high
                                       m
                                 high
                            m
                                  low
                                  m
                           high
    L.r[7]=L.r[6];即把27换成97
    L.r[6]=L.r[5];即把97换成76
    L.r[5]=L.r[4];
    L.r[4]=L.r[3];
    L.r[3]=L.r[2];
    L.r[2]=L.r[0];即把27插入L.r[2];
        (27)(13  27 38 49 65 76 97)
i=8:  (49)(13  27 38 49 65 76 97) 
                low                          high
                                 m
                                      low
                                            m
                                      high
                                        m
                                high
        L.r[9]=L.r[8];
        L.r[8]=L.r[7];
        L.r[7]=L.r[6];
        L.r[6]=L.r[5];
        L.r[5]=L.r[0];
   (49)(13  27 38 49 49 65 76 97)
O(n^2)      
2_路插入排序:
[初始关键字]: 49 38 65 97 76 13 27 49
i=1:   (49)
     first|| final
i=2:    (49)                                       (38)
     final|                                              |first
i=3:    (49 65)                                    (38)
                   |final                                |first
i=4:    (49 65 97)                               (38)
                       |final                             |first
i=5:   (49 65 76 97)                           (38)
                          |final                         |first
i=6:   (49 65 76 97)                           (13 38)
                          |final                           |first
i=7:   (49 65 76 97)                    (13 27 38)
                           |final                   |first
i=8:   (49 49 65 76 97       13 27 38)
                               |final    |first
     
    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值