排序,插入排序,交换排序,选择排序,归并排序

排序

内部排序

Ⅰ:插入类

①:直接插入排序(直插法):将一个记录插入到一个已经排序好的有序表
设表尾最后那个是“要插入表的元素”

#define MaxSize 10// 最大长度
#define ok 0

typedef int KeyType;//整形
typedef int InfoType;


typedef struct{
	KeyType key;
	InfoType otherinfo;
}RedType; 
typedef struct{
	RedType r[MaxSize+1];//r[0]闲置或用做哨兵单元
	int length;//顺序表长度 
}SqList,*SqListLink;
typedef SqList HeapType; 
//--------------比较函数-----------------//
int LT(KeyType key1,KeyType key2){
	if (key1<key2) return 1;//1
	else  return  0;//0
}
//---------------排序------------------//
void InsertSort(SqList *L){
     int i=1,j=0;
     for(;i<=(*L).length;++i)
         if(LT((*L).r[i].key,(*L).r[i-1].key)){
          //靠近表头的比靠近表尾的大
          (*L).r[0]=(*L).r[i];//将小(相对靠近表尾)的入哨兵     
          (*L).r[i]=(*L).r[i-1];//将大(相对靠近表头)的向后
        for(j=i-2;LT((*L).r[0].key,(*L).r[j].key);--j)
                 (*L).r[j+1]=(*L).r[j];//与哨兵做比较,比哨兵大 移位
          (*L).r[j+1]=(*L).r[0];///哨兵
         }
 	printf("排序好后数据:");
	for(i=1;i<=(*L).length;i++){
		printf("% 2d",(*L).r[i].key);
	}
	return ok; 

}

void Init_SqList(SqList *L){//初始化顺序表,下面还要用,只在这里写
	 printf("有个数据不符合规律 哨兵设置为0,共多少个数据:");
	 int length;
	 scanf("%d",&length); 
	 int i=0;
	 printf("哨兵:");
	 scanf("%d",&(L->r[0].key)); 
	 for(i=1;i<=length;i++){//L.r[0]为哨兵位置 
	    scanf("%d",&(L->r[i].key)); 
	 }
	 L->length=length;
	 printf("初始化数据\n");
	 for(i=0;i<=L->length;++i){
	 	printf("% 2d",L->r[i].key);
	 }
	 return ok;
}
void SqListTest(){//相当于main   下同
	SqList L;
	Init_SqList(&L);
   InsertSort(&L);
}

原来的key: 38,49,65,97,76(要进行排序的那个)在这里插入图片描述关键字比较次数:(n²)/4,时间复杂度:O(n²)

折半插入排序(半插法)

void BInsertSort(SqList *L){
     int i,j,m,low,high;
     for(i=2;i<=L->length;++i){
     L->r[0]=L->r[i];//从“表尾”进一个排一个;表尾从2~3~.....最后一个
     low=1,high=i-1;
     while(low<=high){
      m=(low+high)/2;
      if(LT(L->r[0].key,L->r[m].key)) high=m-1;
      else low=m+1;
     }//while
     for(j=i-1;j>=high+1;--j) L->r[j+1]=L->r[j];
          L->r[high+1]=L->r[0];
     }//for
}
void SqListTest(){
	SqList L;
	Init_SqList(&L);
    BInsertSort(&L);
}

在这里插入图片描述时间复杂度为O(n²)

③:希尔排序
按增量进行两两交换,最后一个增量必须为1
在这里插入图片描述

void ShellInsert(SqList *L,int dk){
     int i,j;
     for(i=dk+1;i<=L->length;++i){
       if(LT(L->r[i].key,L->r[i-dk].key)){//后面的比前面的小
       L->r[0]=L->r[i];//小的入哨兵
       for(j=i-dk;j>0&&LT(L->r[0].key,L-r[j].key);j-=dk)
             L->r[j+dk]=L->r[j];//换位
       L->r[j+dk]=L->r[0];
       }//if
     }//for i
	 	printf("排序ing--:\n");
		 for(j=1;j<=L->length;++j)
		    printf("% d",L->r[j].key);		
}
void ShellSort(SqList *L,int dlta[],int t){
     int k;
     	for(k=0;k<t;++k) ShellInsert(L,dlta[k]); 
	printf("排序后:");
	for(k=1;k<=L->length;++k) printf("% 2d",L->r[k].key); 
}
void SqListTest(){
    SqList L;int sum,i;
	printf("共有dlta值几个:");
	scanf("%d",&sum); 
	int dlta[sum];
	Init_SqList(&L);
    printf("输入dlta值:\n");
    for(i=0;i<sum;++i)
        scanf("%d",&dlta[i]);
	ShellSort(&L,dlta,sum);
}

在这里插入图片描述时间复杂度:O(n的1.3次方到n的1.5次方)

Ⅱ:交换类

快速选择排序(快排)
选择一个枢轴

int Partition(SqList *L,int low,int high){//一次快排
    int pivotkey;//枢轴
    L-r[0]=L->r[low];
    pivotkey=L->r[low].key;
    while(low<high){
    while(low<high&&L->r[high].key>=pivotkey) --high;//大于枢轴,high就一直往‘左’移动位置
   L->r[low]=L->r[high];
    while(low<high&&L->r[low].key>=pivotkey) ++low;//大于枢轴,low就一直往‘右’移动位置
    L->r[high]=L->r[low];
    }//while
    L->r[low]=L->r[0];
    return low;
}
void Qsort(SqList *L,int low,int high){
	int pivotloc;
	if(low<high){
	pivotloc=Partition(L,low,high);//一次快排定位后已经分为两个“比较”有序的俩半 
	Qsort(L,low,pivotloc-1);
	Qsort(L,pivotloc+1,high);
	} 
}
void SqListTest(){
      SqList L;
      Init_SqList(&L);
      Qsort(&L,1,8);
}

在这里插入图片描述时间复杂度:平均:**O(nlog2n),最坏:O(n²)**进来的是有序的

Ⅲ:选择类

①堆排序
分为大顶堆和小顶堆,一次堆排序只输出一个堆顶值
成为堆的条件:1小顶堆 Ki<=K₂i && Ki<=K(₂i+1) 2大顶堆 Ki>=K₂i && Ki>=K(₂i+1)
大顶堆多次堆排序的演绎:每排一次得到最大值就放在
在这里插入图片描述

void HeapOnceAdjust(HeapType *H,int s,int m){//s为顶点下标 m表示表长
        RedType rc=H->r[s];//堆顶先赋值给RC
		int j;
		for(j=2*s;j<m;j*=2){
			if(j<m&&LT(H->r[j].key,H->r[j+1].key)) ++j;//j为Key较大值得下标
			if(!LT(rc.key,H->r[j].key)) break;
			H->r[s]=H->r[j];s=j;
		} 
  	    H->r[s]=rc;//H->r[s] 原来的消息已经移走上去了 
  }
  
  void HeapSort(HeapType *H){
  	   int i=0;
  	   for(i=(H->length)/2;i>0;--i){
  	   	HeapOnceAdjust(H,i,H->length);
		 }//将数据变成大顶堆
		 for(i=H->length;i>1;--i){
		 	H->r[0]=H->r[1];
		 	H->r[1]=H->r[i];
		 	H->r[i]=H->r[0];
		 	HeapOnceAdjust(H,1,i-1);
		 }
	printf("排序后:\n");
	for(i=1;i<=H->length;i++){
		printf("% 2d",H->r[i].key);
	} 
  } 
 void SqListTest(){
      SqList L;
      	Init_SqList(&L);
      	    HeapSort(&L);
}

在这里插入图片描述时间复杂度:O(nlog2n)

Ⅳ:归并类

时间复杂度:O(nlog2n) 其中m,n是两个有序表的表长
相当于:有序表+有序表=有序表
表中,二二做比较,大的排后,小的排前,多次归并即可。
2-路归并的思想:将一维数组中 前后相邻的两个有序序列归并为一个有序序列
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200331235230358.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3OTc2OTMz,size_16,color_FFFFFF,t_70#pic_center

归并的趟数:s=logm(n),m是归并的路数,n是关键字次数。
时间复杂度:O(nlog2n)

比较

在这里插入图片描述1:如果输入序列是有序的:直插算法最快结束,快排最慢结束
2:不稳定的算法有:快排,希尔,选排,堆排(快 些 选 堆 美女)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值