前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >算法(二)

算法(二)

作者头像
1ess
发布2021-11-01 15:57:37
2010
发布2021-11-01 15:57:37
举报
文章被收录于专栏:0x7c00的专栏

算法(二)

發佈於 2019-03-10

本篇开始,我们来看看在工作中比较常用的两大算法之一的排序算法。

基本概念及分类

假设含有 n 个记录的序列为 {r1, r2, …, rn},其相应的关键字分别为 {k1, k2, …, kn},需确定 1, 2, …, n 的一种排列 p1, p2, …, pn,使其相应的关键字满足 kp1 <= kp2 <= … <= kpn 非递减(或非递增)关系,即使得序列成为一个按关键字有序的序列 {rp1, rp2, …, rpn},这样的操作就称为排序。

注意: 我们在排序问题中,通常将数据元素称为记录。

排序的稳定性

假设 ki = kj (1 <= i <= n, 1 <= j <= n, i 不等于 j),且在排序前的序列中 ri 领先于 rj(即 i < j)。如果排序后 ri 仍领先于 rj,则称所用的排序方法时稳定的,反之,则称所用的排序方法时不稳定的。

内排序和外排序

根据排序过程中待排序的记录是否全部放置于内存中,排序分为: 内排序和外排序。 内排序是在排序整个过程中,待排序的所有记录全部被放置在内存中。 外排序是由于待排序的记录个数太多,不能同时放置在内存,整个排序过程需要在内外存之间多次交换数据才能进行。

冒泡排序

冒泡排序(Bubble Sort): 一种交换排序,他的基本思想是,两两比较相邻记录的关键字,如果反序则交换,知道没有反序记录为止。

简单实现

代码语言:javascript
复制
class SqList
{
    public const int MaxSize = 20;
    public int[] Data = new int[MaxSize];
    public int Length;

    public SqList(int[] data)
    {
        var length = (data.Length > MaxSize ? MaxSize : data.Length);
        Length = length;
        for (var i = 0; i < length; i++)
        {
            Data[i] = data[i];
        }
    }
    public void Swap(ref int a, ref int b)
    {
        var temp = a;
        a = b;
        b = temp;
    }
    /// <summary>
    /// 只能算是简单交换排序,经历一遍内存循环,将最小值置于第 i 位
    /// </summary>
    public void BubbleSort0()
    {
        for (var i = 0; i < Length; i++)
        {
            for (var j = i + 1; j < Length; j++)
            {
                if (Data[i] > Data[j])
                {
                    Swap(ref Data[i], ref Data[j]);
                }
            }
        }
    }
    
    public void ShowDatas()
    {
        var data = new int[Length];
        for (var i = 0; i < Length; i++)
        {
            data[i] = Data[i];
        }
        Console.WriteLine(string.Join("->", data));
    }

}

经典冒泡排序

代码语言:javascript
复制
/// <summary>
/// 经典冒泡排序,从后向前依次比较,较小值上浮
/// </summary>
public void BubbleSort1()
{
    for (var i = 0; i < Length; i++)
    {
        for (var j = Length -1; j > i; j--)
        {
            if (Data[j] < Data[j-1])
            {
                Swap(ref Data[j], ref Data[j-1]);
            }
        }
    }
}

优化冒泡排序

代码语言:javascript
复制
/// <summary>
/// 优化冒泡排序,设置标记,当存在交换时,设置标记,否则退出循环
/// </summary>
public void BubbleSort2()
{
    var flag = false;
    for (var i = 0; i < Length && !flag; i++)
    {
        flag = true;
        for (var j = Length - 1; j > i; j--)
        {
            if (Data[j] >= Data[j - 1]) continue;
            Swap(ref Data[j], ref Data[j - 1]);
            flag = false;
        }
    }
}

简单选择排序

简单选择排序(Simple Selection Sort)就是通过 n - i 次关键字间的比较,从 n - i + 1 个记录中选出关键字最小的记录,并和第 i 个记录交换。

代码语言:javascript
复制
/// <summary>
/// 简单选择排序,通过比较第 i 位与其之后的最小值,若存在,则交换
/// </summary>
public void SelectionSort()
{
    for (var i = 0; i < Length; i++)
    {
        var minIndex = i;
        for (var j = i + 1; j < Length; j++)
        {
            if (Data[minIndex] > Data[j])
            {
                minIndex = j;
            }
        }

        if (minIndex != i)
        {
            Swap(ref Data[i], ref Data[minIndex]);
        }
    }
}

直接插入排序

直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排序好的有序表中,从而得到一个新的、记录数加一的有序表。

代码语言:javascript
复制
/// <summary>
/// 每次遍历将第 i 位记录取出,将之前的记录后移,再将第 i 位记录置于正确位置
/// </summary>
public void InsertionSort()
{
    for (var i = 1; i < Length; i++)
    {
        if (Data[i] >= Data[i - 1]) continue;
        var temp = Data[i];
        for (var j = i-1; j >=0 && Data[j] > temp; j--)
        {
            Swap(ref Data[j+1], ref Data[j]);
        }
    }
}

快速排序

快速排序(Quick Sort)的基本思想是: 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分继续进行排序,以达到整个序列有序的目的。

代码语言:javascript
复制
public void QuickSort(int left, int right)
{
    var low = left;
    var high = right;
    var temp = Data[left];

    if (left > right)
    {
        return;
    }

    while (low != high)
    {
        while (Data[high] >= temp && low < high)
        {
            high--;
        }

        while (Data[low] <= temp && low < high)
        {
            low++;
        }

        if (low < high)
        {
            Swap(ref Data[low], ref Data[high]);
        }
    }

    Swap(ref Data[low], ref Data[left]);
    QuickSort(left, low - 1);
    QuickSort(low + 1, right);
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本概念及分类
    • 排序的稳定性
      • 内排序和外排序
      • 冒泡排序
        • 简单实现
          • 经典冒泡排序
            • 优化冒泡排序
            • 简单选择排序
            • 直接插入排序
            • 快速排序
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档