[C++]排序模板(含C++模板代码)

本文详细介绍了C++实现的几种排序算法模板,包括插入排序、冒泡排序、选择排序、归并排序和快速排序。文章阐述了每种排序算法的特点、时间复杂度,并提供了C++代码模板。同时,对算法的正确性进行了证明,讨论了不同排序算法的适用场景和优劣对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

排序模板

一、插入排序

  • 特点:stable sort、In-place sort
  • 最优复杂度:当输入数组就是排好序的时候,复杂度为O(n),而快速排序在这种情况下会产生O(n^2)的复杂度。
  • 最差复杂度:当输入数组为倒序时,复杂度为O(n^2)
  • 插入排序比较适合用于“少量元素的数组”。

伪代码:

image

C++模板:

template <typename T>
void Insertion_Sort(T *array, size_t length) {
    if (length <= 1) {
        return;
    } else {
        for (int i = 1; i != length; i++) {
            int j = i - 1;
            T key = array[i];
            while (j >= 0 && array[j] > key) {
                array[j + 1] = array[j];
                j--;
            }
            array[j + 1] = key;
        }
    }
}

证明算法正确性:

循环不变式:在每次循环开始前,A[1…i-1]包含了原来的A[1…i-1]的元素,并且已排序。

初始:i=2,A[1…1]已排序,成立。

保持:在迭代开始前,A[1…i-1]已排序,而循环体的目的是将A[i]插入A[1…i-1]中,使得A[1…i]排序,因此在下一轮迭代开 始前,i++,因此现在A[1…i-1]排好序了,因此保持循环不变式。

终止:最后i=n+1,并且A[1…n]已排序,而A[1…n]就是整个数组,因此证毕。

二、冒泡排序

  • 特点:stable sort、In-place sort
  • 思想:通过两两交换,像水中的泡泡一样,小的先冒出来,大的后冒出来。
  • 最坏运行时间:O(n^2)
  • 最佳运行时间:O(n^2)(当然,也可以进行改进使得最佳运行时间为O(n))

伪代码:

image

C++模板:

template <typename T>
void Bubble_Sort(T *array, size_t length) {
    for (int i = 0; i != length - 1; i++) {
        for (int j = 0; j + i != length - 1; j++) {
            if (array[j] > array[j + 1]) {
                T temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }
}

证明算法正确性:

运用两次循环不变式,先证明第4-6行的内循环,再证明外循环。

内循环不变式:在每次循环开始前,A[j]是A[j…n]中最小的元素。

初始:j=n,因此A[n]是A[n…n]的最小元素。
保持:当循环开始时,已知A[j]是A[j…n]的最小元素,将A[j]与A[j-1]比较,并将较小者放在j-1位置,因此能够说明A[j-1]是A[j-1…n]的最小元素,因此循环不变式保持。
终止:j=i,已知A[i]是A[i…n]中最小的元素,证毕。

接下来证明外循环不变式:在每次循环之前,A[1…i-1]包含了A中最小的i-1个元素,且已排序:A[1]<=A[2]<=…<=A[i-1]。

初始:i=1,因此A[1..0]=空,因此成立。
保持:当循环开始时,已知A[1…i-1]是A中最小的i-1个元素,且A[1]<=A[2]<=…<=A[i-1],根据内循环不变式,终止时A[i]是A[i…n]中最小的元素,因此A[1…i]包含了A中最小的i个元素,且A[1]<=A[2]<=…<=A[i-1]<=A[i]
终止:i=n+1,已知A[1…n]是A中最小的n个元素,且A[1]<=A[2]<=…<=A[n],得证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值