算法之七大经典排序

针对现实中的排序问题,算法有七把利剑可以助你马道成功。

首先排序分为四种:

交换排序: 包括冒泡排序,快速排序。

选择排序: 包括直接选择排序,堆排序。

插入排序: 包括直接插入排序,希尔排序。

合并排序: 合并排序。

冒泡排序简单来说就是利用两个for循环来进行排序,由前一个数据和后一个数据比较,如果前一个大于后一个则交换,这样如果从头循环一次,就会找到整个列表中最大的那个数,将其固定在最后一位,所以循环n次就能确定所有顺序了。

#include <stdio.h>

void swap(int *a, int *b); //交换两个数

int main()
{
	int     str[10];
	int     i, j;
	//初始化数组为10 9 8 7 6 5 4 3 2 1
	for (i = 0; i < 10; i++)
	{
		str[i] = 10 - i;
	}
	//排序,从a[0]开始排,从小到大
	for (i = 0; i < 10; i++)
	{
		for (j = i + 1; j < 10; j++)
		{
			if (str[i] > str[j])
			{
				swap(&str[i], &str[j]);
			}
		}
	}
        //将十个数输出
	for (i = 0; i < 10; i++)
		printf("%d\n", str[i]);
	return    0;
}
void swap(int *a, int *b)
{
	int     c;
	 c = *a;
	*a = *b;
	*b =  c;
}

快速排序是冒泡排序的升级版,一般stl里使用的都是快排,效率还是可以的。

主要思想就是选择第一个数为标准数b,先从右开始找,找一个比b小的数赋值给left位上的数,也就是b,之后从左开始找,找一个比b大的数与right位上的数,因为right位上的数已经赋值给left了,所以其中right位置上的数是多余的,之后只要left<right就循环下去,当left == right的时候,将b赋值在left位上,现在的局面就是left左边都是比b小的,left右边都是比b大的。

然后在分别求两边的快排,写一个小递归就OK了,递归的退出条件就是left>right,其实就是已经将列表分解成单个数据的时候就退出递归,返回数据。

int quicksort(vector<int> &v, int left, int right){
        if(left < right){
                int key = v[left];
                int low = left;
                int high = right;
                while(low < high){
                        while(low < high && v[high] > key){
                                high--;
                        }
                        v[low] = v[high];
                        while(low < high && v[low] < key){
                                low++;
                        }
                        v[high] = v[low];
                }
                v[low] = key;
                quicksort(v,left,low-1);
                quicksort(v,low+1,right);
        }
}

java版

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;

namespace QuickSort
{
    public class Program
    {
        static void Main(string[] args)
        {
            //5次比较
            for (int i = 1; i <= 5; i++)
            {
                List<int> list = new List<int>();

                //插入200个随机数到数组中
                for (int j = 0; j < 200; j++)
                {
                    Thread.Sleep(1);
                    list.Add(new Random((int)DateTime.Now.Ticks).Next(0, 10000));
                }

                Console.WriteLine("\n第" + i + "次比较:");

                Stopwatch watch = new Stopwatch();

                watch.Start();
                var result = list.OrderBy(single => single).ToList();
                watch.Stop();

                Console.WriteLine("\n系统定义的快速排序耗费时间:" + watch.ElapsedMilliseconds);
                Console.WriteLine("输出前是十个数:" + string.Join(",", result.Take(10).ToList()));

                watch.Start();
                new QuickSortClass().QuickSort(list, 0, list.Count - 1);
                watch.Stop();

                Console.WriteLine("\n俺自己写的快速排序耗费时间:" + watch.ElapsedMilliseconds);
                Console.WriteLine("输出前是十个数:" + string.Join(",", list.Take(10).ToList()));

            }
        }
    }

    public class QuickSortClass
    {

        ///<summary>
/// 分割函数
///</summary>
///<param name="list">待排序的数组</param>
///<param name="left">数组的左下标</param>
///<param name="right"></param>
///<returns></returns>
        public int Division(List<int> list, int left, int right)
        {
            //首先挑选一个基准元素
            int baseNum = list[left];

            while (left < right)
            {
                //从数组的右端开始向前找,一直找到比base小的数字为止(包括base同等数)
                while (left < right && list[right] >= baseNum)
                    right = right - 1;

                //最终找到了比baseNum小的元素,要做的事情就是此元素放到base的位置
                list[left] = list[right];

                //从数组的左端开始向后找,一直找到比base大的数字为止(包括base同等数)
                while (left < right && list[left] <= baseNum)
                    left = left + 1;

                //最终找到了比baseNum大的元素,要做的事情就是将此元素放到最后的位置
                list[right] = list[left];
            }
            //最后就是把baseNum放到该left的位置
            list[left] = baseNum;

            //最终,我们发现left位置的左侧数值部分比left小,left位置右侧数值比left大
//至此,我们完成了第一篇排序
            return left;
        }

        public void QuickSort(List<int> list, int left, int right)
        {
            //左下标一定小于右下标,否则就超越了
            if (left < right)
            {
                //对数组进行分割,取出下次分割的基准标号
                int i = Division(list, left, right);

                //对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序
                QuickSort(list, left, i - 1);

                //对“基准标号“右侧的一组数值进行递归的切割,以至于将这些数值完整的排序
                QuickSort(list, i + 1, right);
            }
        }
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-09 11:30:31

算法之七大经典排序的相关文章

算法系列15天速成——第三天 七大经典排序【下】

原文:算法系列15天速成--第三天 七大经典排序[下] 今天跟大家聊聊最后三种排序: 直接插入排序,希尔排序和归并排序. 直接插入排序: 这种排序其实蛮好理解的,很现实的例子就是俺们斗地主,当我们抓到一手乱牌时,我们就要按照大小梳理扑克,30秒后, 扑克梳理完毕,4条3,5条s,哇塞......  回忆一下,俺们当时是怎么梳理的. 最左一张牌是3,第二张牌是5,第三张牌又是3,赶紧插到第一张牌后面去,第四张牌又是3,大喜,赶紧插到第二张后面去, 第五张牌又是3,狂喜,哈哈,一门炮就这样产生了.

算法系列15天速成——第一天 七大经典排序【上】

原文:算法系列15天速成--第一天 七大经典排序[上] 今天是开篇,得要吹一下算法,算法就好比程序开发中的利剑,所到之处,刀起头落. 针对现实中的排序问题,算法有七把利剑可以助你马道成功. 首先排序分为四种: 交换排序: 包括冒泡排序,快速排序. 选择排序: 包括直接选择排序,堆排序. 插入排序: 包括直接插入排序,希尔排序. 合并排序: 合并排序. 那么今天我们讲的就是交换排序,我们都知道,C#类库提供的排序是快排,为了让今天玩的有意思点, 我们设计算法来跟类库提供的快排较量较量.争取KO对手

算法系列15天速成——第二天 七大经典排序【中】

原文:算法系列15天速成--第二天 七大经典排序[中] 首先感谢朋友们对第一篇文章的鼎力支持,感动中.......  今天说的是选择排序,包括“直接选择排序”和“堆排序”. 话说上次“冒泡排序”被快排虐了,而且“快排”赢得了内库的重用,众兄弟自然眼红,非要找快排一比高下. 这不今天就来了两兄弟找快排算账. 1.直接选择排序: 先上图: 说实话,直接选择排序最类似于人的本能思想,比如把大小不一的玩具让三岁小毛孩对大小排个序, 那小孩首先会在这么多玩具中找到最小的放在第一位,然后找到次小的放在第二位

七大经典排序(Java版)

. 冒泡排序: 通过相邻的两个数的比较, 根据需要决定是否将两个数互换位置, 然后将比较往前(或往后)推进. 最简单的排序算法,直接上代码. for(i=0;i<length-1;i++) for(j=i+1;j<length;j++) if(arrayVal[i]>arrayVal[j]) { //置换位置 temp=arrayVal[i]; arrayVal[i]=arrayVal[j]; arrayVal[j]=temp; } } 选择排序: "选择排序"就是第

七大经典排序算法,了解一下?

常见排序算法总结与实现 本文使用Java实现这几种排序.以下是对排序算法总体的介绍. 冒泡排序 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.这步做完后,最后的元素会是最大的数. 针对所有的元素重复以上的步骤,除了最后一个. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较. 时间复杂度:O(n^2),最优时间复杂度:O(n),平均时间复杂度:O(n^2) 1public static void bubbl

经典排序算法 - 希尔排序Shell sort

经典排序算法 - 希尔排序Shell sort 希尔排序Shell Sort是基于插入排序的一种改进,同样分成两部分, 第一部分,希尔排序介绍 第二部分,如何选取关键字,选取关键字是希尔排序的关键 第一块希尔排序介绍 准备待排数组[6 2 4 1 5 9] 首先需要选取关键字,例如关键是3和1(第一步分成三组,第二步分成一组),那么待排数组分成了以下三个虚拟组: [6 1]一组 [2 5]二组 [4 9]三组 看仔细啊,不是临近的两个数字分组,而是3(分成了三组)的倍数的数字分成了一组, 就是每

经典排序算法总结与实现 ---python

原文:http://wuchong.me/blog/2014/02/09/algorithm-sort-summary/ 经典排序算法在面试中占有很大的比重,也是基础,为了未雨绸缪,在寒假里整理并用Python实现了七大经典排序算法,包括冒泡排序,插入排序,选择排序,希尔排序,归并排序,快速排序,堆排序.希望能帮助到有需要的同学.之所以用Python实现,主要是因为它更接近伪代码,能用更少的代码实现算法,更利于理解. 本篇博客所有排序实现均默认从小到大. 一.冒泡排序 BubbleSort 介绍

【最全】经典排序算法(C语言)

本文章包括所有基本排序算法(和其中一些算法的改进算法): 直接插入排序.希尔排序.直接选择排序.堆排序.冒泡排序.快速排序.归并排序.基数排序. 算法复杂度比较: 算法分类 一.直接插入排序 一个插入排序是另一种简单排序,它的思路是:每次从未排好的序列中选出第一个元素插入到已排好的序列中. 它的算法步骤可以大致归纳如下: 从未排好的序列中拿出首元素,并把它赋值给temp变量: 从排好的序列中,依次与temp进行比较,如果元素比temp大,则将元素后移(实际上放置temp的元素位置已经空出) 直到

经典排序算法

经典排序算法(via  kkun) 经典排序算法,以下文章参考了大量网上的资料,大部分都给出了出处 这一系列重点在理解,所以例子什么的都是最简单的情况,难免失误之处,多指教 大多数排序算法都给出了每一步的状态,以方便初学者更容易理解,通俗易懂,部分难以理解的排序算法则给出了大量的图示,也算是一个特色吧 经典排序算法 - 快速排序Quick sort 经典排序算法 - 桶排序Bucket sort 经典排序算法 -  插入排序Insertion sort 经典排序算法 - 基数排序Radix so