数据结构-排序

一、排序的概述
1.什么是排序?
使表中的元素按关键字有序的过程。如order by id desc

2.排序算法的评价指标
时间复杂度。空间复杂度。稳定性。
算法稳定性:关键字相同的元素在排序之后相对位置保持不变,即是稳定的;否则不稳定。
稳定的算法不一定比不稳定的好,看实际需求。

 3.排序算法的分类
内部排序:数据都在内存中,如对数组进行排序。关注如何优化时间和空间复杂度
外部排序:数据太多,无法放入内存。如一个超过8G的大文件无法全部放入内存。关注如何使得读写磁盘次数更少。
 

二、插入排序
1.插入排序
A 算法思想
每次将一个待排序的记录按其关键字大小插入到前面已排好序的子序列中,直到全部记录插入完成。

B 算法实现
从第二个元素开始遍历,如果遍历的当前元素小于其前驱元素,则子序列中大于该元素的序列后移,将当前元素插入到指定位置。
带哨兵的插入算法:a[0]不存放元素,而是存放每次遍历的元素,这样在移动元素时,可以不用考虑指针越界问题,少写一步j >=0。

/*
* 直接插入排序(不带哨兵)
* 存放序列的数组a,与序列长度n
*/
void InsertSort(int a[],int n)
{
    for (int i=1;i<n;i++) { //从第二个元素开始遍历
        if (A[i] < A[i-1])  //如果遍历的元素小于字序列的最后一个元素,需要插入到指定位置
        {
            int temp = A[i]; //暂存A[i]
            //大于temp之后的元素全部后移
            for(int j=i-1; j>=0 && A[j]>temp; --j) { //所有大于temp的元素向后挪位
                A[j+1] = A[j];
            }
            A[j+1] = temp;  //赋值到插入位置
        }
    }
}

/**
* 直接插入排序(带哨兵)
* 存放序列的数组a,序列长度n,数组下标从1开始,0空出作为哨兵
*/
void InsertSort(int a[],int n)
{
    for (int i=2;i<=n;i++) { //从第二个元素开始遍历 , a[0]空出不存元素
        if (A[i] < A[i-1])  //如果遍历的元素小于字序列的最后一个元素,需要插入到指定位置
        {
            A[0] = A[i]; //复制为哨兵,A[0]不存元素
            for(int j = i-1;A[0] < A[j]; --j) { //不用每次都判断j>=0
                A[j+1] = A[j];
            }
            A[j+1] = A[0];  //赋值到插入位置
        }
    }
}

C 算法效率分析
空间复杂度:定义的辅助变量都是常数级,与问题规模n无关,所以空间复杂度为O(1)
时间复杂度:主要来自对比关键字,移动元素。
若元素已经有序,最好情况,从第二个元素开始,需遍历n-1次,时间复杂度为O(n)。
若元素全部逆序,最坏情况,从第二个元素开始,每次遍历都需要移动元素,时间复杂度为O(n^2)。

平均复杂度为O(n^2),算法稳定

顺序查找找到插入位置,可以用顺序表或链表。

2.优化-折半插入排序
先用折半查找找到应该插入的位置,再移动元素。

 


 分析:比起直接插入,比较关键字次数减少,但是移动次数未变,所以时间复杂度依然是O(n^2)。算法稳定。
折半查找找到指定位置,所以仅适用于顺序表。

3.希尔排序

三、交换排序
基于“交换”的排序:根据序列中的两个元素关键字的比较结构来对换这两个记录在序列中的位置。
1.冒泡排序
A 算法思想(牢记)
从后往前(从前往后)两两比较相邻元素的值,若为逆序(A[i-1] > A[i]),则交换它们,直到序列比较完,完成一趟交换排序。对于每一趟最小的数像泡泡一样冒到最后,所以又叫冒泡排序。

B 过程分析

第一趟:27 < 49 不交换 =》 13<27 不交换 =》 76 >13交换 =》 97>13 交换  依次往下。

元素13逐渐“冒泡”到第一个元素位置。
第二趟

第三趟,直到某趟遍历未发生元素交换,说明表已经有序。

C 代码实现
 

void BubbleSort(int a[],int n)
{
    for(int i=0;i<n-1;i++) {
        bool flag = flase;
        for (int j=n-1;j>i;j--) {
            if (a[j-1] > a[j]) {
                swap(a[j-1],a[j]);
                flag = true;
            }
        }
        if (!flag) {  //本趟遍历未发生交换 表已经有序
             return ;
        }
    }
}

D 算法分析
 

 

 

 

2.快速排序

 

 

 

 

 

 

 

 

 

四、选择排序

1.简单选择排序

 

 

 

2.堆排序
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
排序是计算机科学中常见的操作,它将一组元素按照特定的顺序重新排列。排序算法的目标通常是将元素按照升序或降序排列。 常见的排序算法有很多种,每种算法都有不同的时间复杂度和空间复杂度。以下是几种常见的排序算法: 1. 冒泡排序(Bubble Sort):比较相邻的两个元素,如果顺序不正确就交换位置,每次遍历将一个最大(最小)的元素移到最后(最前)。时间复杂度为O(n^2)。 2. 插入排序(Insertion Sort):将数组分为已排序和未排序两部分,每次从未排序部分取出一个元素,插入已排序部分的适当位置。时间复杂度为O(n^2)。 3. 选择排序(Selection Sort):每次从未排序部分选择一个最小(最大)的元素放到已排序部分的末尾。时间复杂度为O(n^2)。 4. 快速排序(Quick Sort):选取一个基准元素,将数组划分为两个子数组,小于基准元素的放在左边,大于基准元素的放在右边,然后对子数组进行递归排序。时间复杂度平均情况下为O(nlogn),最坏情况下为O(n^2)。 5. 归并排序(Merge Sort):将数组递归分成两个子数组,然后对子数组进行排序,最后将两个已排序的子数组合并成一个有序数组。时间复杂度为O(nlogn)。 6. 堆排序(Heap Sort):将数组构建成一个最大(最小)堆,每次从堆顶取出最大(最小)元素放到已排序部分的末尾,然后调整堆使其满足堆的性质。时间复杂度为O(nlogn)。 这里只介绍了几种常见的排序算法,每种算法都有其适用的场景和优缺点。在实际应用中,根据数据规模和性能要求选择合适的排序算法非常重要。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值