关闭

基本排序算法

303人阅读 评论(0) 收藏 举报
分类:

代码:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

/*---------------------------改进冒泡排序------------------------------------*/
// 算法复杂度O(n^2)
vector<int> BubbleSort(vector<int> vec)
{
    int length = vec.size();
    bool flag = true;   //避免在剩余的数已经有序的情况下做无意义的循环判断
    for (int i = 0; i < length; i++)
    {
        flag = false;
        for (int j = length - 1; j > 0;j--)
        {
            if (vec[j] < vec[j-1])
            {
                swap(vec[j], vec[j -1]);
                flag = true;            //如果有数据交换,则flag为true
            }
        }
    }
    return vec;
}

//简单选择排序, 算法复杂度O(n^2)
vector<int> SimpleSelectionSort(vector<int> vec)
{
    int length = vec.size();
    int min = 0;        //保存每次找到的最小值的下标
    for (int i = 0; i < length-1; i++)
    {
        min = i;
        for (int j = i + 1; j < length; j++)
        {
            if (vec[j] < vec[min])
            {
                min = j;
            }
        }

        if (i != min)
            swap(vec[i], vec[min]);

    }

    return vec;
}


/*---------------------------简单插入排序------------------------------------*/
// 算法复杂度O(n^2)

vector<int> SimpleInsertSort(vector<int> vec)
{
    int length = vec.size();
    for (int i = 1, j = 0; i < length; i++)
    {
        if (vec[i] < vec[i - 1])
        {
            int temp = vec[i];
            for (j = i - 1; j >= 0 && vec[j] > temp; j--)
            {
                vec[j + 1] = vec[j];
            }
            vec[j + 1] = temp;
        }
    }
    return vec;
}

/*---------------------------希尔排序------------------------------------*/
//不稳定排序,算法复杂度O(n^(3/2))
vector<int> ShellSort(vector<int> vec)
{
    int j = 0;
    int increment = vec.size();
    do 
    {
        increment = increment / 3 + 1;
        for (int i = increment; i < vec.size() ; i++)
        {
            if (vec[i] < vec[i - increment])
            {
                int temp = vec[i];
                for (j = i - increment; j >= 0 && temp < vec[j];j -= increment)
                {
                    vec[j + increment] = vec[j];
                }
                vec[j + increment] = temp;
            }           
        }
    } while (increment > 1);
    return vec;
}

/*---------------------------堆排序------------------------------------*/

//堆排序,不稳定排序算法,时间复杂度为O(nlogn)
//不适合排序序列个数较少的情况,开始建堆所需的比较次数较多

void swap(vector<int> &temp, int head, int last)    //交换堆顶与未经排序子序列的最后一个结点
{
    int tmp = temp[head];
    temp[head] = temp[last];
    temp[last] = tmp;
}
void HeapAdjust(vector<int> &vec, int low, int high)
{
    int temp = vec[low];
    for (int j = low * 2; j <= high; j *= 2)
    {
        if (j < high && vec[j] < vec[j + 1])
            j++;
        if (temp >= vec[j])
            break;
        vec[low] = vec[j];
        low = j;
    }
    vec[low] = temp;  
}
vector<int> HeapSort(vector<int> vec)
{
    vector<int> temp(vec.size() + 1, 0);
    temp[0] = -1;
    for (int i = 0; i < vec.size(); i++)
    {
        temp[i + 1] = vec[i];
    }

    //构建大根堆
    for (int i = vec.size() / 2; i > 0; i--)
    {
        HeapAdjust(temp, i, vec.size());
    }

    //堆排序
    for (int i = vec.size(); i > 1; i--)
    {
        swap(temp, 1, i);
        HeapAdjust(temp, 1, i-1);
    }

    for (int i = 1; i < temp.size();i++)
    {
        vec[i - 1] = temp[i];
    }


    return vec;
}

/*---------------------------归并排序,递归实现------------------------------------*/
//合并
void Merge(vector<int>& subvec, int p, int mid, int q)
{
    int a = mid - p + 1;
    int b = q - mid;
    vector<int> L(a + 1, 0);
    vector<int> R(b + 1, 0);
    for (int i = 0; i < a; i++)
        L[i] = subvec[p + i];
    for (int j = 0; j < b; j++)
        R[j] = subvec[mid + j + 1];
    L[a] = R[b] = INT_MAX;

    int i = 0, j = 0;
    for (int k = p; k < q + 1; k++)
    {
        if (L[i] <= R[j])
        {
            subvec[k] = L[i];
            i++;
        }
        else
        {
            subvec[k] = R[j];
            j++;
        }
    }
}

//分解
void RSort(vector<int> &subvec, int p, int q)
{
    if (p < q)
    {
        int mid = (p + q) / 2;
        RSort(subvec, p, mid);
        RSort(subvec, mid + 1, q);
        Merge(subvec, p, mid, q);       //合并

    }
}
vector<int> MergeSort(vector<int> vec)
{
    int length = vec.size();
    RSort(vec,0,length-1);          //分解为多个子问题求解,分治思想
    return vec;
}

/*---------------------------归并排序,非递归实现------------------------------------*/

//将有序的v1[i...m]和有序的v1[m+1...n]归并到有序的v2中
void Merge2(vector<int>& v1, vector<int>& v2, int i, int m, int n)
{
    int k = 0, j = 0;
    for (k = i, j = m + 1; i <= m && j <= n; k++)
    {
        if (v1[i] < v1[j])

            v2[k] = v1[i++];
        else

            v2[k] = v1[j++];
    }

    if (i <= m)
    {
        for (int t = 0; t <= m - i; t++)
            v2[k+t] = v1[i+t];
    }
    if (j <= n)
    {
        for (int t = 0; t <= n-j; t++)
            v2[k+t] = v1[j+t];
    }
}

//将v1中相邻长度为gap的子序列两两归并到v2中

void MergeAdjacent(vector<int>& v1, vector<int>& v2, int gap, int len) 
{
    int i = 0;
    while (i <= len-2*gap)
    {
        Merge2(v1, v2, i, i + gap - 1, i + 2 * gap - 1);
        i += 2 * gap;
    }

    if (i < len - gap + 1 )         //当不够两组进行归并时,如果剩余元素超过k个元素,仍然进行归并
        Merge2(v1, v2,i, i + gap - 1, len-1);
    else                            //如果剩余元素不超过k个元素时,直接复制给中间数组
    {
        for (int j = i; j < len; j++)
        {
            v2[j] = v1[j];
        }

    }

    for (i = 0; i < len; i++)
        v1[i] = v2[i];
}
vector<int> MergeSort2(vector<int> vec)
{
    int length = vec.size();
    vector<int> vec2(length, 0);
    int k = 1;
    while (k < length)
    {
        MergeAdjacent(vec, vec2, k, length);
        k = 2 * k;
    }
    return vec;
}

/*---------------------------快速排序------------------------------------*/

int Partition(vector<int>& vec, int low, int high)
{
    int pivotkey = vec[low];    //用子表中的第一个元素作为枢轴
    while (low < high)
    {
        while (vec[high] >= pivotkey && low < high)
            high--;
        swap(vec[low], vec[high]);
        while (vec[low] <= pivotkey && low < high)
            low++;
        swap(vec[low], vec[high]);
    }

    return low;
}
void QSort(vector<int>& vec, int low, int high)
{
    int pivot;
    if (low < high)
    {
        pivot = Partition(vec, low, high);  //算出中枢值
        QSort(vec, low, pivot - 1);
        QSort(vec, pivot + 1, high);
    }

}
vector<int> QuickSort(vector<int> vec)
{
    int length = vec.size();
    QSort(vec, 0, length - 1);
    return vec;
}

/*---------------------------计数排序------------------------------------*/

//算法复杂度O(n),线性时间排序算法,适合于小范围的集合的排序
vector<int> CountSort(vector<int> vec)
{
    int length = vec.size();
    vector<int> result(length,0);   //保存结果

    int max;    //保存最大值
    //找出vec中的最大值
    if (length > 0)
    {
         max = vec[0];
        for (int i = 1; i < length; i++)
        {
            if (max < vec[i])
                max = vec[i];
        }
    }

    //创建保存计数的vector
    vector<int> temp(max + 1, 0);

    //保存最后结果
    //vector<int> result;
    for (int i = 0; i < length;i++)
    {
        temp[vec[i]] += 1;
    }

    //temp[i] 包含了小于等于i的个数,以确定i的位置
    for (int i = 1; i <= max;i++)
    {
        temp[i] += temp[i - 1];
    }

    for (int j = length - 1; j >= 0;j--)
    {
        result[temp[vec[j]]-1] = vec[j];
        temp[vec[j]] = temp[vec[j]] - 1;
    }
    return result;

}

/*---------------------------改进的计数排序------------------------------------*/
//与标准的相比,可以节约一些空间,
vector<int> CountSort2(vector<int> vec)
{
    int length = vec.size();


    int max;    //保存最大值
    //找出vec中的最大值
    if (length > 0)
    {
        max = vec[0];
        for (int i = 1; i < length; i++)
        {
            if (max < vec[i])
                max = vec[i];
        }
    }

    //创建保存计数的vector
    vector<int> temp(max + 1, 0);

    for (int i = 0; i < length; i++)
    {
        temp[vec[i]] += 1;
    }

    int j = 0;
    for (int i = 0; i <= max; i++)
    {
        while (temp[i]--)
            vec[j++] = i;
    }


    return vec;
}

/*---------------------------基数排序------------------------------------*/

//算法时间复杂度O(n),具有线性的时间代价
//计数排序有两种方式,LSD由数值的最右边(低位)开始,而MSD则相反,由数值的最左边开始
//LSD适用于位数少的数值,如果位数多,MSD的效率更好
/*
MSD实现是一个递归的过程:
(1)首先根据最高位的关键码K1排序,得到若干个对象组,即分到若干个桶中,每个桶中有相同的关键字
(2)再分别对每个桶根据关键码K2进行排序,再根据K2的分成若干个子桶,依次类推...
(3)最后把所有桶中的序列连接起来既构成了一个有序的序列
*/

//这里实现LSD,MSD类似
//获取x这个数的第d位的数字
//因为LSD由数值的最右边开始的,123的第1位为3,第二位为2,...
int getDigit(int x, int d)
{
    int a[] = { 1, 1, 10, 100 };    //本例中,最大数是百位数,因此a[]中最大为100
    return (x / a[d] % 10);
}

vector<int> RadixSortLSD(vector<int> vec)
{
    int length = vec.size();
    int d = 3;      //本例中,最大的只有3位数
    int count[10];  //每个桶排序
    int j;

    int* bucket = new int[length];

    //对每位进行排序
    for (int k = 1; k <= d; k++)
    {
        for (int i = 0; i < 10; i++)     //利用计数排序的思想用数组模拟桶
            count[i] = 0;

        //统计各个桶中所盛数据个数
        for (int i = 0; i < length; i++)
        {
            count[getDigit(vec[i], k)]++;
        }

        for (int i = 1; i < 10; i++)    
        {
            count[i] += count[i - 1];   
        }
        //这时,count[i]表示第i个桶的右边界索引
        for (int i = length - 1; i >= 0; i--)
        {
            j = getDigit(vec[i], k);
            bucket[count[j] - 1] = vec[i];
            count[j]--;
        }

        //此时,count[i]为第i个桶的左边界

        //将桶中的数据收集出来
        for (int i = 0, j = 0; i < length; i++, j++)
            vec[i] = bucket[j];

    }

    delete[] bucket;

    return vec;
}

int main()
{
    vector<int> array = { 9, 1, 5, 8, 3, 7, 4, 6, 2 };
    vector<int> result;

    //冒泡排序
    result = BubbleSort(array);
    cout << "冒泡排序后: ";
    for (auto it = result.begin(); it != result.end(); it++)
        cout << *it << " ";
    cout << endl << endl;

    //选择排序
    result = SimpleSelectionSort(array);
    cout << "简单选择排序后: ";
    for (auto it = result.begin(); it != result.end(); it++)
        cout << *it << " ";
    cout << endl << endl;

    //插入排序
    result = SimpleInsertSort(array);
    cout << "简单插入排序后: ";
    for (auto it = result.begin(); it != result.end(); it++)
        cout << *it << " ";
    cout << endl << endl;

    //希尔排序
    result = ShellSort(array);
    cout << "希尔排序后: ";
    for (auto it = result.begin(); it != result.end(); it++)
        cout << *it << " ";
    cout << endl << endl;


    //堆排序
    result = HeapSort(array);
    cout << "堆排序后: ";
    for (auto it = result.begin(); it != result.end(); it++)
        cout << *it << " ";
    cout << endl << endl;

    //归并排序,递归实现
    result = MergeSort(array);
    cout << "(递归实现)归并排序后: ";
    for (auto it = result.begin(); it != result.end(); it++)
        cout << *it << " ";
    cout << endl<<endl;

    //归并排序,非递归实现
    result = MergeSort2(array);
    cout << "(非递归实现)归并排序后: ";
    for (auto it = result.begin(); it != result.end(); it++)
        cout << *it << " ";
    cout << endl << endl;

    //快速排序
    result = QuickSort(array);
    cout << "快速排序后: ";
    for (auto it = result.begin(); it != result.end(); it++)
        cout << *it << " ";
    cout << endl<<endl;

    //计数排序
    result = CountSort(array);
    cout << "计数排序后: ";
    for (auto it = result.begin(); it != result.end(); it++)
        cout << *it << " ";
    cout << endl << endl;

    //计数排序2
    result = CountSort2(array);
    cout << "改进的计数排序后: ";
    for (auto it = result.begin(); it != result.end(); it++)
        cout << *it << " ";
    cout << endl << endl;

    //基数排序
    vector<int> array2 = { 329, 457, 657, 83, 436, 720, 355, 221, 983};
    cout << "基数排序前: ";
    for (auto it = array2.begin(); it != array2.end(); it++)
        cout << *it << " ";
    cout << endl;
    result = RadixSortLSD(array2);
    cout << "LSD基数排序后: ";
    for (auto it = result.begin(); it != result.end(); it++)
        cout << *it << " ";
    cout << endl << endl;

    system("pause");
    return 0;
}

测试:

这里写图片描述

0
0
查看评论

基本排序算法

选择排序 将要排序的对象分作两部份,一个是已排序的,一个是未排序的,从后端未排序部份选择一个最小值,并放入前端已排序部份的最后一个,例如: 排序前:70 80 31 37 10 1 48 60 33 80 [1] 80 31 37 10 70 48 60 33 80 选...
  • gnssxgj
  • gnssxgj
  • 2013-09-09 15:00
  • 115

基本排序算法(全)

7个基本排序算法:冒泡,选择,插入 快排,归并,堆 桶 已实际运行过冒泡:时间复杂度O(n^2) 选择:同上 插入:数据基本有序的情况下O(n)能达到桶排序速度, 平均和坏的时间复杂度为O(n^2)快排: 平均性能比较好的O(nlog2N) 归并: 需要额外的空间辅助 堆:3个部件: 建堆,排序,...
  • u010308400
  • u010308400
  • 2015-11-13 18:43
  • 233

基本排序算法:Python实现

基本排序算法,包括冒泡排序,插入排序,选择排序,堆排序,快速排序等。   【冒泡排序】 复杂度是n*n #coding:utf8 #author:HaxtraZ #description:冒泡排序 def bubblesort1(a): #每次找到一个最小元素,放到数组...
  • zz958712568
  • zz958712568
  • 2013-08-23 15:21
  • 882

基本排序算法代码

稳定的排序有;插入排序,归并排序,冒泡排序,基数排序; 不稳定的排序有:快速排序,堆排序,选择排序,shell排序。 快速排序: 主要是运用i,j两个下标的移动找到参照点的最终位置。  void quickSort(int *array, int left, int right...
  • waynewying
  • waynewying
  • 2013-04-01 10:52
  • 227

Java基本排序算法

排序大的分类可以分为两种,内排序和外排序,在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,那么称之为外排序 内排序分为一下几类 - 插入排序: 直接插入排序,二分法插入排序,希尔排序 - 选择排序:简单选择排序,堆排序。 - 交换排序: 冒泡排序,快速排序 -...
  • bell10027
  • bell10027
  • 2015-12-29 17:29
  • 179

排序-基本排序算法

import java.io.InputStreamReader; import java.io.BufferedReader; /** * Class  SortDemo * Description  简单排序有insertSort,BubbleSort,SelectS...
  • cdl2008sky
  • cdl2008sky
  • 2009-02-18 18:06
  • 381

数据结构基本排序算法

冒泡排序 package com.lei.go; public class BubbleSort { public static void main(String [] args) { int [] a ={1,3,5,12,4,6,1}; a=bubbleSort(a, 7);...
  • w5761499123
  • w5761499123
  • 2016-10-04 13:45
  • 223

基本排序算法-java

import java.util.Arrays; import java.util.Scanner; import com.sun.scenario.effect.Merge; import com.sun.xml.internal.ws.dump.LoggingDumpTube.Position...
  • u011514514
  • u011514514
  • 2017-04-03 18:24
  • 102

java基本排序算法

8种排序之间的关系: 1, 直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排 好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数 也是排好顺序的。如此反复循环,直到全部排好顺序。 (2)实例 ...
  • ljl18566743868
  • ljl18566743868
  • 2016-11-08 23:55
  • 83

基本排序算法--归并排序

#include using namespace std; void Merge(int a[], int first, int mid, int last) { int *b = new int[last - first + 1]; int first1 = first; int last...
  • zhaoyuxiang126
  • zhaoyuxiang126
  • 2015-08-25 22:11
  • 136
    个人资料
    • 访问:79137次
    • 积分:3038
    • 等级:
    • 排名:第13670名
    • 原创:222篇
    • 转载:97篇
    • 译文:0篇
    • 评论:3条
    最新评论