IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构九大排序方法总结(C++实现) -> 正文阅读

[数据结构与算法]数据结构九大排序方法总结(C++实现)

复习数据结构时,仿照王道数据结构考研复习指导,复现九大排序算法,包括插入排序(直接插入排序,折半插入排序,希尔排序),交换排序(冒泡排序,快速排序),选择排序(简单选择排序,堆排序),归并排序基数排序

以下算法均采用C++实现。

插入排序

直接插入排序

直接插入排序是每次将一个待排序的记录插入已经排好序的子序列,直到全部记录插入完成。
即:1.从前面的有序子表中查找出待插入元素应该被插入的位置;2.给插入位置腾出空间,将待插入元素复制到表中的插入位置

void InsertSort1(int A[], int n)
{
    int i, j;
    for (i = 2; i <= n; i++)
    {
        if (A[i] < A[i - 1])
        {
            //方法一
            // A[0] = A[i]; // A[0]为哨兵
            // for (j = i - 1; A[j] > A[0]; j--) //元素后移,寻找插入位置
            // {
            //     A[j + 1] = A[j];
            // }
            // A[j + 1] = A[0];

            //方法二
            A[0] = A[i];
            j = i - 1;
            do
            {
                A[j + 1] = A[j];
                j--;
            } while (j >= 1 && A[j] > A[0]);
            A[j + 1] = A[0];
        }
    }
}

其中,A[0]为哨兵元素。
直接插入排序:时间复杂度O(n2),空间复杂度O(1),稳定的排序算法。

折半插入排序

折半插入排序减少比较元素的次数。

void InsertSort2(int A[], int n)
{
    int i, j;
    for (i = 2; i <= n; i++)
    {
        A[0] = A[i];
        int l = 1, r = i - 1;
        while (l <= r) //先折半查找出元素的待插入位置,然后统一地移动待插入位置之后的所有元素
        {
            int mid = l + (r - l) / 2;
            if (A[0] < A[mid])
                r = mid - 1;
            else
                l = mid + 1;
        }
        for (j = i - 1; j >= r + 1; j--)
        {
            A[j + 1] = A[j];
        }
        A[r + 1] = A[0];
    }
}

折半插入排序时间复杂度仍为O(n2),是一种稳定的排序算法。

希尔排序

希尔排序又称为缩小增量排序,即把相隔某个增量的记录组成一个子表,对各个子表分别进行直接插入排序,当整个表中的元素已经“基本有序”时,再对全体记录进行一次直接插入排序。

void ShellSort(int A[], int n)
{
    int i, j, dk;
    for (dk = n / 2; dk >= 1; dk = dk / 2)
    {
        for (i = dk + 1; i <= n; i++)
            if (A[i] < A[i - dk])
            {
                A[0] = A[i];
                for (j = i - dk; j > 0 && A[j] > A[0]; j -= dk)
                {
                    A[j + dk] = A[j];
                }
                A[j + dk] = A[0]; // 插入
            }
    }
}

希尔排序,时间复杂度约为O(n1.3),最坏情况O(n2),空间复杂度O(1),不稳定的排序。

交换排序

冒泡排序

冒泡排序,从后往前(或从前往后)两两比较相邻元素的值,若为逆序,则交换,重复n-1趟。

void BubbleSort(int A[], int n)
{
    for (int i = 0; i < n - 1; i++)
    {
        bool flag = false;
        for (int j = n - 1; j > i; j--)
        {
            if (A[j] < A[j - 1])
            {
                swap(A[j], A[j - 1]);
                flag = true;
            }
        }
        if (!flag)
            return;
    }
}

冒泡排序,空间复杂度O(1),时间复杂度O(n2),稳定的排序方法

快速排序

快速排序的基本思想是基于分治法的,任取一个元素pivot作为枢轴,划分为两部分。左半部分<pivot,右半部分>pivot。快速排序的partition有很多种实现方法,这里采用王道408中描述的方法进行实现。

int Partition(int A[], int low, int high)
{
    int pivot = A[low];
    while (low < high)
    {
        while (low < high && A[high] >= pivot) 
            high--;
        A[low] = A[high]; //将比枢轴小的元素移到左端
        while (low < high && A[low] <= pivot) 
            low++;
        A[high] = A[low]; //将比枢轴大的元素移到右端
    }
    A[low] = pivot;
    return low;
}
void QuickSort(int A[], int low, int high)
{
    if (low < high)
    {
        int pivotpos = Partition(A, low, high);
        QuickSort(A, low, pivotpos - 1);
        QuickSort(A, pivotpos + 1, high);
    }
}

快速排序:空间复杂度O(logn),时间复杂度O(nlogn),不稳定的排序方法,快速排序是所有内部排序算法中平均性能最优的排序算法

选择排序

简单选择排序

简单选择排序,每一趟选择关键字最小的元素,作为有序子序列的第i个元素。

void SelectSort(int A[], int n)
{
    for (int i = 0; i < n - 1; i++)
    {
        int min = i;
        for (int j = i + 1; j < n; j++)
        {
            if (A[min] > A[j])
            {
                min = j;
            }
        }
        if (min != i)
            swap(A[min], A[i]);
    }
}

选择排序,时间复杂度O(n2),空间复杂度O(1),不稳定的排序算法

堆排序

咕咕咕

归并排序

归并排序,将两个或两个以上的有序表组合成一个新的有序表,将前后相邻的两个有序表归并为一个有序表,两两进行归并。

void Merge(int A[], int left, int mid, int right)
{
    int B[1001];
    for (int i = left; i <= right; i++)
    {
        B[i] = A[i]; //将A中所有元素复制到B,辅助数组
    } 
    int s1 = left, s2 = mid + 1, s = left; //s是指向当前位置的指针
    while (s1 <= mid && s2 <= right)
    {
        if (B[s1] <= B[s2]) A[s++] = B[s1++];
        else if (B[s1] > B[s2]) A[s++] = B[s2++];
    }
    while (s1 <= mid)
    {
        A[s++] = B[s1++]; // 若第一个表未检测完,复制
    }
    while (s2 <= right)
    {
        A[s++] = B[s2++]; // 若第二个表未检测完,复制
    }
}
void MergeSort(int A[], int left, int right)
{
    if (left < right)
    {
        int mid = (left + right) / 2;
        MergeSort(A, left, mid);
        MergeSort(A, mid + 1, right);
        Merge(A, left, mid, right);
    }
}

归并排序,空间复杂度O(n),时间复杂度O(nlogn),稳定的排序算法

基数排序

咕咕咕

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-04 15:50:05  更:2022-03-04 15:50:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:44:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码