经典算法题每日演练——第二十三题 鸡尾酒排序

简介:


这篇我们继续扯淡一下鸡尾酒排序,为了知道为啥取名为鸡尾酒,特意看了下百科,见框框的话,也只能勉强这么说了。

 

要是文艺点的话,可以说是搅拌排序,通俗易懂点的话,就叫“双向冒泡排序”,我想作为码农的话,不可能不知道冒泡排序,

冒泡是一个单向的从小到大或者从大到小的交换排序,而鸡尾酒排序是双向的,从一端进行从小到大排序,从另一端进行从大

到小排序。

从图中可以看到,第一次正向比较,我们找到了最大值9. 

                      第一次反向比较,我们找到了最小值1.

                      第二次正向比较,我们找到了次大值8.

                      第二次反向比较,我们找到了次小值2

                      。。。

                     最后就大功告成了。

 

下面我们看看代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Xsl;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> list = new List<int>() { 8, 1, 4, 2, 9, 5, 3 };

            Console.WriteLine("\n排序前 => {0}\n", string.Join(",", list));

            list = CockTailSort(list);

            Console.WriteLine("\n排序后 => {0}\n", string.Join(",", list));

            Console.Read();
        }

        /// <summary>
        /// 鸡尾酒排序
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        static List<int> CockTailSort(List<int> list)
        {
            //因为是双向比较,所以比较次数为原来数组的1/2次即可。
            for (int i = 1; i <= list.Count / 2; i++)
            {
                //从前到后的排序 (升序)
                for (int m = i - 1; m <= list.Count - i; m++)
                {
                    //如果前面大于后面,则进行交换
                    if (m + 1 < list.Count && list[m] > list[m + 1])
                    {
                        var temp = list[m];

                        list[m] = list[m + 1];

                        list[m + 1] = temp;
                    }
                }

                Console.WriteLine("正向排序 => {0}", string.Join(",", list));

                //从后到前的排序(降序)
                for (int n = list.Count - i - 1; n >= i; n--)
                {
                    //如果前面大于后面,则进行交换
                    if (n > 0 && list[n - 1] > list[n])
                    {
                        var temp = list[n];

                        list[n] = list[n - 1];

                        list[n - 1] = temp;
                    }
                }

                Console.WriteLine("反向排序 => {0}", string.Join(",", list));
            }

            return list;
        }
    }
}

 

从结果上面看,我们会发现,当数组有序的时候,我们还会继续往下排,知道完成length/2次,这个就跟没优化之前的冒泡排序一样,

此时我们可以加上一个标志位IsSorted来判断是否已经没有交换了,如果没有,提前退出循环。。。

/// <summary>
        /// 鸡尾酒排序
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        static List<int> CockTailSort(List<int> list)
        {
            //判断是否已经排序了
            var isSorted = false;

            //因为是双向比较,所以比较次数为原来数组的1/2次即可。
            for (int i = 1; i <= list.Count / 2; i++)
            {
                //从前到后的排序 (升序)
                for (int m = i - 1; m <= list.Count - i; m++)
                {
                    //如果前面大于后面,则进行交换
                    if (m + 1 < list.Count && list[m] > list[m + 1])
                    {
                        var temp = list[m];

                        list[m] = list[m + 1];

                        list[m + 1] = temp;

                        isSorted = true;
                    }
                }

                Console.WriteLine("正向排序 => {0}", string.Join(",", list));

                //从后到前的排序(降序)
                for (int n = list.Count - i - 1; n >= i; n--)
                {
                    //如果前面大于后面,则进行交换
                    if (n > 0 && list[n - 1] > list[n])
                    {
                        var temp = list[n];

                        list[n] = list[n - 1];

                        list[n - 1] = temp;

                        isSorted = true;
                    }
                }

                //当不再有排序,提前退出
                if (!isSorted)
                    break;

                Console.WriteLine("反向排序 => {0}", string.Join(",", list));
            }

            return list;
        }

相关文章
|
7月前
|
算法
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
|
4月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
204 7
|
4月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
165 8
|
5月前
|
搜索推荐 Shell
解析排序算法:十大排序方法的工作原理与性能比较
解析排序算法:十大排序方法的工作原理与性能比较
143 9
|
5月前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
63 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
6月前
|
大数据 UED 开发者
实战演练:利用Python的Trie树优化搜索算法,性能飙升不是梦!
在数据密集型应用中,高效搜索算法至关重要。Trie树(前缀树/字典树)通过优化字符串处理和搜索效率成为理想选择。本文通过Python实战演示Trie树构建与应用,显著提升搜索性能。Trie树利用公共前缀减少查询时间,支持快速插入、删除和搜索。以下为简单示例代码,展示如何构建及使用Trie树进行搜索与前缀匹配,适用于自动补全、拼写检查等场景,助力提升应用性能与用户体验。
91 2
|
5月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
50 0
|
5月前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
102 0
|
7月前
|
搜索推荐 算法 Java
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
该博客文章通过UML类图和Java源码示例,展示了如何使用适配器模式将QuickSort类和BinarySearch类的排序和查找功能适配到DataOperation接口中,实现算法的解耦和复用。
74 1
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
|
7月前
|
算法 搜索推荐 Java
算法实战:手写归并排序,让复杂排序变简单!
归并排序是一种基于“分治法”的经典算法,通过递归分割和合并数组,实现O(n log n)的高效排序。本文将通过Java手写代码,详细讲解归并排序的原理及实现,帮助你快速掌握这一实用算法。
64 0