排序——直接插入排序&&折半插入排序

文章目录

  • 前言
  • 一、排序的基本概念
    • 1. 排序的定义
    • 2. 排序的分类
      • 1) 稳定排序
      • 2) 不稳定排序
  • 二、插入排序
    • 1. 直接插入排序
      • 1)直接插入排序算法分析
    • 2. 直接插入排序代码
    • 3. 直接插入排序时间复杂度
    • 4. 折半插入排序
    • 5. 折半插入排序代码
  • 总结


前言

  1. 排序的基本概念
  2. 数据结构稳定排序
  3. 数据结构不稳定排序
  4. 排序的种类
  5. 排序的代码
  6. 直接插入排序算法

一、排序的基本概念

1. 排序的定义

  1. 定义:将数据表调整为按关键字从小到大或从大到小的次序排列的过程
  2. 排序的分类:增排序,减排序,内部排序,外部排序
  3. 稳定排序:在排序过程中,如果关键字相同的两个元素的相对次序不变,则称为稳定的排序
  4. 不稳定的排序:当相同的关键字的领先关系在排序过程中不发生变化者,则称所用的排序方法是不稳定的
  5. 算法的稳定性:排序中两个元素相等,排序后位置不发生变化说明算法稳定,主要是对算法性质的描述,不能衡量算法优劣
  6. 内部算法通常进行:比较+移动,基数排序不是基于比较的

2. 排序的分类

1) 稳定排序

插入排序、冒泡排序、归并排序、基数排序


2) 不稳定排序

选择排序、快速排序、希尔排序、堆排序


二、插入排序

基本思想:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中,直到全部记录插入完成,每次插入便又多一个元素排好相对顺序

1. 直接插入排序

排序——直接插入排序&&折半插入排序_第1张图片

1)直接插入排序算法分析

基本思想:
将待排序表看做是左、右两个部分,其中左边为有序区,右边为无序区,整个排序过程就是将右边无序区中的元素逐个插入到左边的有序区中,以构成新的有序区。

  1. 将第i个元素插入到前面已经排序好的i-1的元素中,步骤为:
    (1)查找出L(i)在L[1…i-1]中位置k
    (2)将L[k…i-1]中所有元素全部后移一位
    (3)将L(i)复制到L(k)

  2. 稳定性:每次插入元素总是从后往前比较后再移动,所以算法稳定

  3. 适用性:适用于顺序存储和链式存储

  4. 性质
    (1)在基本有序情况下,效率最高,不需移动元素
    (2)排序了i以后可以确定有i个元素连续,而不一定有元素已在最后的位置上

2. 直接插入排序代码

void   InsertSort(elementtype r[n+1])
{
  for (  i=2 ;  i<=n ; ++ i ) 
    {
      r[0]=r[i]; // 将待插入记录复制为哨兵
      j=i-1;
      while(r[j]>r[0]) 
      {r[j+1]=r[j];
         j--;
        }
     r[ j+1]=r[0];      //插入到正确位置
    }
 }

#include 
void main()
{ 
int a[7]={3,2,1,5,0,-1,7};
   int x,i,j;
  for(i=1;i<=6;i++)
   {
x=a[i];
    j=i-1;
while(x<a[j]&&j>=0)
{a[j+1]=a[j]; j- -;}  
       a[j+1]=x;       
}

3. 直接插入排序时间复杂度

从时间耗费角度来看,主要时间耗费在关键字比较和移动元素上。
直接插入排序的时间复杂度:

  1. 最好情况:初始有序,为O(n);
  2. 最坏情况:初始逆序,为O(n2);
  3. 平均时间复杂度T(n)= O(n2)
  4. 直接插入排序方法是稳定的排序方法。
  5. 直接插入排序算法简便,比较适用于待排序记录数目较少且基本有序的情况。当待排记录数目较大时,直接插入排序的性能就不好

4. 折半插入排序

  1. 定义:也叫二分插入排序,先折半查找出元素的待插入位置,然后再统一移动待插入位置之后的所有元素

5. 折半插入排序代码

void InsertSort(ElemType A[],int n){
	int i,j,low,high,mid;
	for(i=0;i<n;i++){
	A[0]=A[i];
	low=1;
	high=i-1;
	while(low<=high){
		mid=(low+high)/2;
		if(A[mid].key>A[0].key)
			high=mid-1;
		else
			low=mid+1;
	}
	for(j=i-1;j>=high+1;--j)
		A[j+1]=A[j];
	A[high+1]=A[0]}
}
  1. 效率:减少了元素比较的次数,约为O(nlog2n),该比较次数与待排序初始状态无关,仅取决于n;移动次数没有改变,依赖于待排序初始状态,时间复杂度为 O(n2)

  2. 稳定性:算法稳定
    排序思想:
    在找第i个记录的插入位置时,前i-l个记录已排序,将第i个记录的排序码 keyi和已排序的前i-1个的中间位置记录的排序码进行比较,如果keyi小于中间位置记录排序码,则可以在前半部继续使用二分法查找,否则在后半部继续使用二分法查找,直到查找范围为空,即可确定ri的插入位置。


总结

  1. 排序的基本概念
  2. 数据结构稳定排序
  3. 数据结构不稳定排序
  4. 排序的种类
  5. 排序的代码
  6. 直接插入排序算法
  7. 折半插入排序算法

你可能感兴趣的:(数据结构,数据结构,排序算法,算法)