数据结构-08排序算法

数据结构-08排序算法

01直接插入排序

算法思想: 每次将一个待排序的记录按照关键字大小插入到前面已排好序的子序列,直到全部记录插入即可。

#include<iostream>
using namespace std;
void InsertSort(int arr[], int len){
    int i, j, temp;     // 定义临时指针i,j,以及中间变量temp
    for(i=1; i<len; i++){   // 默认第一个位置已经确定,从第二个元素开始
        if(arr[i]<arr[i-1]){    // 若a[i]关键字小于前驱,则向前移动当前元素位置
            temp = arr[i];      // 用temp暂存A[i]
            for(j=i-1; arr[j]>temp&&j>=0; j--){     // 检查前面的元素,将大于temp的元素后移
                arr[j+1] = arr[j];
            }
            arr[j+1] = temp;    // 将temp复制到插入位置
        }
    }
}

算法分析:
空间复杂度:O(1)
时间复杂度:
最好:O(n) 所有元素都已经排好序,每个元素仅比较一次(共n-1次)
最坏:O(n2) 所有元素均为逆序,移动元素次数1+2+3+…+n-1
平均:O(n2))
稳定性:稳定。
适用性:顺序存储和链式存储的线性表

02 折半插入排序

算法思想: 对于查找待排序元素(当前元素)的待插入位置的算法从顺序查找变为了折半查找。
算法实现:

#include <stdio.h>

void InsertSort(int arr[], int len){
    int i,j,temp,low,high,mid;
    for(i=1;i<len;i++){
        if(arr[i]<arr[i-1]){    // 若a[i]关键字小于前驱,则向前移动当前元素位置
            temp = arr[i];      // 用temp暂存arr[i]
            low=0;high=i-1;     // 定义折半查找的范围
            while(low<=high){       // 按照递增排序, 否则就是high=0,low=i-1
                mid=(low+high)/2;   // 取中间点
                if(arr[mid]>temp)
                    high = mid-1;   // 查找左子表
                else
                    low = mid+1;    // 查找右子表
            }
            for(j=i-1;j>=low;j--){
                arr[j+1] = arr[j];      // 统一后移元素,空出插入位置
            }
            arr[j+1] = temp;    // 插入元素
        }
    }
}

算法分析
空间复杂度:O(1)
时间复杂度:
最好:O(n) 所有元素都已经排好序,每个元素仅比较一次(共n-1次)
最坏:O(n2) 所有元素均为逆序,移动元素次数1+2+3+…+n-1
平均:O(n2))
稳定性:稳定
适用性:顺序存储的线性表。(折半查找要求查找表具有随机访问特性)

03 希尔排序

算法思想: 准备一组增量dk[], 按照增量每次将数据元素分为若干子表,这里的dk逐轮减小
如表1为,arr[0],arr[dk],arr[dk+dk]…,表2为:arr[1],arr[1+dk],arr[1+2*dk]…以此类推
如此,对每个子表进行排序,最后一次的dk值一定为1,此时相当于对查找表进行一次直接插入排序。

算法实现

#include<stdio.h>

void ShellSort(int arr[], int len){
    int i,j,temp,dk=len;
    while(true){
        dk = dk/2;
        if(dk==0)   break;
        for(i=dk;i<len;i++){    // 下标i从dk开始,对应每次子表的第二个元素
            if(arr[i]<arr[i-dk]){   // 若当前元素小于前驱,则将前驱元素后移
                temp = arr[i];
                for(j=i-dk;j>=0&&arr[j]>temp;j-=dk){    // 这里只需将子表中的元素间隔后移即可
                    arr[j+dk] = arr[j];
                }
                arr[j+dk] = temp;
            }
        }
    }
}

手动模拟:
在这里插入图片描述
在这里插入图片描述

算法分析
空间复杂度:O(1)
时间复杂度:
最好:O(n1.3)
最坏:O(n2)
平均:O(n2))
稳定性:不稳定
适用性:顺序存储的线性表

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值