排序算法系列1:概念介绍及算法比较

 不说话,先上图

背起来是不是很痛苦?在不了解原理的情况下这么硬背是很痛苦,下面就让我们来了解一下这么几种排序是如何实现的以及他们之间的应用比较。

先来了解几个概念:

1.1稳定性:

稳定性是指当两个关键字相同时,两者的排序的结果的顺序是否和排序前顺序一样,如果顺序一样则是稳定的算法,不一样则不稳定。下面给出定义:

1.2内排序和外排序:

内排序是指在整个排序过程中,待排序的所有记录全部放在内存中,但是当待排序的记录过多,只能一部分放在内存中,排序期间不断的在内外存之间交换数据,此为外排序。

影响内排序算法性能的三个方面:

  1. 时间性能:减少关键词比较和移动的次数
  2. 辅助空间
  3. 算法的复杂性

1.3排序分类:

1.根据排序的基本操作分类:

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

2.根据算法的复杂度分类:

简单:冒泡排序、简单选择排序、直接插入排序

改进:希尔排序、堆排序、归并排序、快速排序

 

2.1排序用到的顺序表结构和常用函数:

#ifndef _SQLISH_H
#define _SQLISH_H
#include<stdio.h>
#define MAXSIZE 10
//顺序表结构
typedef struct
{
	int r[MAXSIZE+1];//用于存储要排序的数组
	int length;//用于记录顺序表的长度
}SqList;
//初始化顺序表
void CreateSq(SqList &L)
{
	printf("please input the number of data:\n");
	scanf("%d",&L.length);
	printf("please input %d data:\n",L.length);
	for(int i=1;i<=L.length;i++)
	{
		scanf("%d",&L.r[i]);
	}
}
//打印顺序表
void PrintSq(SqList L)
{
	printf("Ascending output:\n");
	for(int i=1;i<=L.length;i++)
	{
		printf("%d ",L.r[i]);
	}
	printf("\n");
}
//交换函数
void swap(SqList *L,int i,int j)
{
	int temp = L->r[i];
	L->r[i]=L->r[j];
	L->r[j]=temp;
}
#endif

由于每个排序算法都要用到顺序表和交换函数,所以可以把它封装到头文件中

头文件的使用可以看我转载的https://blog.csdn.net/MaxineZhou/article/details/88939367

结构体的使用可以看https://www.cnblogs.com/qyaizs/articles/2039101.html

下面进入正题:

 

优缺点比较:

1、快排的效率最高。但其缺点十分明显:在待排序列基本有序的情况下,会退化成冒泡排序,时间复杂度接近 O(N^2)。
2、希尔排序对增量的选择标准仍然没有较为满意的答案,而增量的选取直接影响排序的效率;
3、在数据规模较大时,归并排序比希尔排序、堆排序速度更快;
4、堆排序在数据规模较小的情况下速度较快,但是随着规模的增大,时间代价也开始和希尔和归并两种排序拉开距离。

适用条件:
(1) n较小,待排序列基本有序时,选择直接插入排序或冒泡排序;
(2)n较小,对稳定性没要求时,用选择排序;
(3)n较大,待排序列随机分布,对稳定性没要求时,用快速排序;
(4)n较大,待排序列基本有序,对稳定性有要求时,在空间允许的情况下,用归并排序;
(5)n较大,待排序列基本有序,对稳定性没要求时,用堆排序;
(6)海量级别的数据,必须按块存放在外存(磁盘)中,用归并排序;;
(7)若待排序的记录的关键字在一个明显有限范围内时,且空间允许是用桶排序。
上面的排序算法,当记录的规模较大时,为避免耗费大量的时间去移动记录,可以用链表作为存储结构。譬如插入排序、归并排序、基数排序都易于在链表上实现,使之减少记录的移动次数。但有的排序方法,如快速排序和堆排序,在链表上却难于实现,在这种情况下,可以提取关键字建立索引表,然后对索引表进行排序。

 

参考书:《大话数据结构》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值