[小明学算法]5.常用排序算法

#include<iostream>
using namespace std;

void Print(int arr[], int length)
{
    for (int i = 0; i < length; i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}

int partition(int a[], int low, int height)
{
    cout << "low: " << low << " height: " << height << endl;
    //完成之后,a[low]元素左侧就全部都是比它大的,右侧都是比它小的
    while (low<height)
    {
        //从最开始的元素开始,从后往前找,找到第一个比它小的,交换
        while (a[low]>a[height])
            height--;
        swap(a[low], a[height]);

        //从开始往后找,找到第一个比它大的,交换
        while (a[height] < a[low])
            low++;
        swap(a[low], a[height]);
    }

    Print(a,7);
    cout << "privotLoc: " << low<<endl;

    //返回当前最低的那个元素排序后的位置

    return low;
}

void Quick(int a[], int low, int height)
{
    if (low >= height)
        return;

    int privotLoc = partition(a, low, height);
    Quick(a, low, privotLoc-1);
    Quick(a, privotLoc+1, height);

}

void Bubble(int a[], int length)
{
    for (int i = 0; i < length; i++)
    {
        for (int j = i; j < length; j++)
        {
            if (a[i] > a[j])
            {
                int t = a[j];
                a[j] = a[i];
                a[i] = t;
            }
        }
    }

    cout << "冒泡:";
    Print(a, 7);
    cout << endl;
}

//将数组a[i,m-1]和a[m,n] 归并到b[i,n]
void Merge(int a[], int b[], int i,int m,int n)
{
    int t = i, k = m;//第一组和第二组的计数器
    int j = i;//数组b的计数器

    //遍历第二组内数据,若第一组内有比当前值小的,将第一组数放到数组b内,否则,将自己放入数组b
    while (k<n+1)
    {
        while(a[t] <a[k]&&t<n)
            b[j++] = a[t++];
        b[j++] = a[k++];
    }
    //遍历第一组剩余数据,将其放入数组b
    while (t<m)
        b[j++] = a[t++];

    for (; i <= n; i++)
    {
        cout << b[i] << " ";
    }
    cout << endl;
}

void MergeSort(int a[],int b[],int length)
{
    int len = 1;

    while (len<length)
    {
        //将数组分为长度为len个等长组,进行合并
        int i = 0;
        while (i + 2 * len<length)
        {
            Merge(a, b, i, i + len, i + 2 * len - 1);
            i+=2 * len;
        }

        //对结尾不等长的组进行合并
        if (i + len <= length)
        {
            Merge(a, b, i, i + len, length - 1);
        }

        //交换a和b,保证下次还是从a归并到b
        swap(a, b);
        //单个小组的长度增倍
        len *= 2;
    }

}

void Selection(int a[], int length)
{
    for (int i = 0; i < length; i++)
    {
        int max=a[i], key=i;
        for (int j = i; j < length; j++)
        {
            if (a[j] > max)
            {
                max = a[j];
                key = j;
            }
        }

        swap(a[i], a[key]);
    }

    cout <<endl<< "选择:";
    Print(a, length);
}

//i是加到末尾的子节点
void MinHeapFixup(int a[], int i)
{
    //建二叉堆,父节点总比子节点小
    for (int j = (i - 1) / 2; j >= 0 && a[j] < a[i]; i = j, j = (j - 1) / 2)
        swap(a[i], a[j]);

}

void MinHeapFixDown(int a[],int length)
{
    int temp,i, j;
    temp = a[0];
    i = 0;
    j = 2 * i + 1;

    while (j<length)
    {
        //1.左右孩子都要找,找到两个孩子中大的那个
        if (j + 1 < length&&a[j + 1] > a[j])
            j++;

        if (a[j] < a[i])
            break;

        a[i] = a[j];
        i = j;
        j = 2 * i + 1;

    }

    a[i] = temp;
}
//堆只能删除顶节点,删除之后还要修复
void MinHeapDelete(int a[],int length)
{
    swap(a[0], a[length - 1]);
    MinHeapFixDown(a, length - 1);
}

void HeapSort(int a[], int length)
{
    cout << "建堆" << endl;
    for (int i = 0; i < length; i++)
    {
        MinHeapFixup(a, i);
        Print(a, length);
    }

    cout << endl;
    cout << "排序" << endl;
    for (int i = 0; i < length; i++)
    {
        MinHeapDelete(a, length - i);
        Print(a, length);
    }

    cout << endl;
    Print(a, length);

}
void main()
{
    int arr[7] = { 1, 5, 6, 16, 15, 122, 76 };
    int b[7];
    Print(arr, 7);
    ////先写个冒泡
    //Bubble(arr, 7);
    ////块排
    //Quick(arr, 0,6);
    //cout << endl << endl;
    ////归并
    //MergeSort(arr, b, 7);
    ////选择
    //Selection(arr, 7);

    //堆排序之前,首先认识到什么是堆,然后建立堆,
    //建完堆,之后,才可以对堆进行排序
    HeapSort(arr, 7);
    Print(arr, 7);
    int a = sizeof(arr);
    cin >> a;
}

  参考:

  http://blog.csdn.net/hguisu/article/details/7776068

  http://blog.csdn.net/morewindows/article/details/6709644

  http://www.blogjava.net/todayx-org/archive/2012/01/08/368091.html

待续

时间: 2024-10-04 23:15:45

[小明学算法]5.常用排序算法的相关文章

算法:常用排序算法

最近整理了常用的排序算法,整理好,留下自己的思考过程. 1.冒泡排序: (1)平均时间复杂度:O(n2) (2)最好时间复杂度:O(n) (3)最坏时间复杂度:O(n2) (5)空间复杂度:O(1) (5)稳定性:稳定 (6)JavaScript实现: function bubble ( arr ) { var len = arr.length; var tmp; // 外层循环负责控制排序的趟数 for(var i = 0; i < len - 1; i++){ // 内层循环负责进行一趟排序

DotNet常用排序算法总结

数据结构和算法对一个程序来说是至关重要的,现在介绍一下几种算法,在项目中较为常用的算法有:冒泡排序,简单选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序等7中算法. 现在介绍选择排序算法,希尔排序算法,快速排序算法. (1).选择排序算法:通过n-i次关键字间的比较,从n-i+1个记录中选择出关键字最小的记录,并和第i(1大于等于i小于等于n)个记录交换. (2).希尔排序:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组.所有距离为d1的倍数的记录放在同一个组中.先在各

Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法

Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配排序(基数排序) 所需辅助空间最多:归并排序 所需辅助空间最少:堆排序 平均速度最快:快速排序 不稳定:快速排序,希尔排序,堆排序. 先来看看 8种排序之间的关系: 1.直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2]

常用排序算法比较与分析

一.常用排序算法简述 下面主要从排序算法的基本概念.原理出发,分别从算法的时间复杂度.空间复杂度.算法的稳定性和速度等方面进行分析比较.依据待排序的问题大小(记录数量 n)的不同,排序过程中需要的存储器空间也不同,由此将排序算法分为两大类:[内排序].[外排序]. 内排序:指排序时数据元素全部存放在计算机的随机存储器RAM中. 外排序:待排序记录的数量很大,以致内存一次不能容纳全部记录,在排序过程中还需要对外存进行访问的排序过程. 先了解一下常见排序算法的分类关系(见图1-1) 图1-1 常见排

七种常用排序算法

七种常用排序算法 一.常见排序算法一览: 时间复杂度: 是一个函数,它定量描述了该算法的运行时间. 空间复杂度:一个算法在运行过程中临时占用存储空间大小的量度. 稳定性:保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同就稳定,反之不稳定. 视觉直观感受 7 种常用的排序算法 二.算法C#实现: 1. 直接插入排序: using System; using System.Collections.Generic; using System.Linq; using Sys

常用排序算法之——快速排序

快速排序的原理: 首先找一个标兵值,等于某一个元素值:遍历数组,将数组分为小于标兵值和大于标兵值的两部分:然后分别对两个部分采用快速排序,递归. 分开数组时,维持一个指针,指向已找到小部分的最后一个元素:一个指针用于遍历. 不稳定排序算法.当数组已经有序时,时间复杂度最差,为O(N2),平均.最优情况下都为O(N lgN). 代码如下: 1 #include <iostream> 2 using namespace std; 3 4 template<typename T> 5 v

javascript常用排序算法实现

毕业后,由于工作中很少需要自已去写一些排序,所以那些排序算法都忘得差不多了,不过排序是最基础的算法,还是不能落下啦,于是找了一些资料,然后用Javascript实现了一些常用的算法,具体代码如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>

常用排序算法实现[交换排序之冒泡排序、快速排序]

相关知识 1. 稳定排序和非稳定排序: 稳定排序算法会依照相等的关键(换言之就是值)维持纪录的相对次序. 如果排序算法是稳定的,就是当有两个有相等关键的纪录R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前. 2. 内排序和外排序 在排序过程中,所有需要排序的数都在内存,并在内存中调整它们的存储顺序,称为内排序: 在排序过程中,只有部分数被调入内存,并借助内存调整数在外存中的存放顺序排序方法称为外排序. 3.算法分类 排序算法从理论上分为如下几类: (1) 交换排序法:

常用排序算法的python实现和性能分析

http://www.cnblogs.com/wiki-royzhang/p/3614694.html 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试题整了一下,可以阶段性的留下些脚印——没办法,平时太忙,基本上没有时间写博客.面试测试开发的话,这些也许能帮得上一些. 这篇是关于排序的,把常见的排序算法和面试中经常提到的一些问题整理了一下.这里面大概有3个需要提到的问题: 虽然专业是数