排序算法的实现(归并,快排,堆排,希尔排序 O(N*log(N)))

今天跟着左老师的视频,理解了四种复杂度为 O(N*log(N))的排序算法,以前也理解过过程,今天根据实际的代码,感觉基本的算法还是很简单的,只是自己写的时候可能一些边界条件,循环控制条件把握不好。

//对于一个int数组,请编写一个选择冒泡算法,对数组元素排序。
//给定一个int数组A及数组的大小n,请返回排序后的数组。
//测试样例:
//[1, 2, 3, 5, 2, 3], 6
//[1, 2, 2, 3, 3, 5]

#include <iostream>
using namespace std;
#include<string>

void printResult(string str,int* A,int n)
{
    cout << str << "的结果:\n";
    for (int i = 0; i < n; i++)
    {
        cout << A[i] <<" ";
    }
    cout << endl;
}
void swap(int *a, int *b)
{
    int temp=*a;
    *a = *b;
    *b = temp;
}

//冒泡排序 O(n^2)
class BubbleSort {
public:
    int* bubbleSort(int* A, int n) {
        // write code here
        for (int i = 0; i<n; i++)
        {
            for (int j = 0; j<n - i - 1; j++)
            {
                if (A[j]>A[j + 1])
                {
                    int temp = A[j];
                    A[j] = A[j + 1];
                    A[j + 1] = temp;
                }
            }
        }
        return A;
    }
};

//请编写一个选择排序算法 O(n^2)
class SelectionSort {
public:
    int* selectionSort(int* A, int n) {
        // write code here
        int k = 0;
        for (int i = 0; i < n-1; i++)
        {
            k = i;
            for (int j = i; j < n; j++)
            {
                if (A[k]>A[j])
                {
                    k = j;
                }
            }
            if (k!=i)
            {
                int temp = A[i];
                A[i] = A[k];
                A[k] = temp;
            }
        }
        return A;
    }
};

//请编写一个插入算法 O(n^2)
class InsertionSort
{
public:
    int* insertionSort(int* A, int n)
    {
        for (int i = 1; i < n; i++)
        {
            int temp = A[i];
            int j = i - 1;
            for (; j >= 0;j--)   //j前面的已经排好序,从后面往前比较,当没有比当前值大的时候bereak;
            {
                if (A[j]>temp)
                {
                    A[j + 1] = A[j];
                }
                else
                {
                    break;
                }
            }
            A[j + 1] = temp;
        }
        return A;
    }
};

//归并排序 O(N*log(N))
class MergeSort {
public:
    int* mergeSort(int* A, int n) {
        // write code here
        mergeSort(A, 0, n - 1);
        return A;
    }
    void mergeSort(int* A, int beg, int end)
    {
        if (beg < end)
        {
            int mid = beg + (end - beg) / 2;
            mergeSort(A, beg, mid);
            mergeSort(A, mid + 1, end);
            merge(A,beg,mid,end);
        }
        return;
    }
    void merge(int* A, int beg_, int mid_, int end_)
    {
        int *B = new int[end_ - beg_ + 1];
        int index1 = beg_;
        int index2 = mid_ + 1;
        int i = 0;
        while (index1<=mid_&&index2<=end_)
        {
            if (A[index1]<=A[index2])
            {
                B[i++] = A[index1++];
            }
            else
            {
                B[i++] = A[index2++];
            }
        }
        while (index1 <= mid_)
        {
            B[i++] = A[index1++];
        }
        while (index2<=end_)
        {
            B[i++] = A[index2++];
        }
        //memcpy(A,B,end_-beg_+1);
        for (int i = 0; i < end_ - beg_ + 1;i++)
        {
            A[beg_+i] = B[i];   //A[beg_++] 不能写,改变了输入参数
        }
        delete[] B;
    }
};

//快速排序 O(N*log(N))
#include <math.h>
class QuickSort {
public:
    int* quickSort(int* A, int n) {
        // write code here
        quickSort(A, 0, n - 1);
        return A;
    }
    void quickSort(int* A, int low, int high)
    {
        if (low <= high)
        {
            int part = partition(A, low, high);
            quickSort(A, low, part - 1);
            quickSort(A, part + 1, high);
        }
        return;
    }

    int partition(int* A, int low, int high)
    {
        int privotKey = A[low];    //基准元素
        while (low < high)
        {        //从表的两端交替地向中间扫描
            while (low < high  && A[high] >= privotKey)
                --high;  //从high 所指位置向前搜索,至多到low+1 位置。将比基准元素小的交换到低端
            swap(&A[low], &A[high]);
            while (low < high  && A[low] <= privotKey)
                ++low;
            swap(&A[low], &A[high]);
        }
        return low;
    }
};
class QuickSort2 {
public:
    int* quickSort(int* A, int n) {
        // write code here
        quickSort(A, 0, n - 1);
        return A;
    }
    void quickSort(int* A, int low, int high)
    {
        if (low <= high)
        {
            int randn = low + rand() % (high - low + 1);  //随机选择关键字的下标
            swap(&A[randn], &A[high]);                      //void swap(int* A,int index1,int index2) //最好都操作下标

            int part = partition(A, low, high);
            quickSort(A, low, part - 1);
            quickSort(A, part + 1, high);
        }
        return;
    }

    int partition(int* A, int low, int high) //O(N)
    {
        //int pivot = A[low];//很多随机选择放在这里面,而且是以值的形式确定,而非下标标记为关键字

        int pivot = low-1; //关键字的位置
        for (int i = low ; i <= high; i++)
        {
            if (A[i] <= A[high])
            {
                swap(&A[i], &A[++pivot]);  //感觉这样会把A数组前面的值覆盖?-->其实没有交换的效果就是把前面的交换到后面
            }
        }
        return pivot;
    }
};

//推排序  O(N*log(N))
class HeapSort {
public:
    int* heapSort(int* A, int n) {
        // write code here
        buildHeap(A, n); //初始时构建堆
        //从最后一个元素开始对序列进行调整
        for (int i = n - 1; i >= 0;i--)
        {
            swap(&A[0], &A[i]);
            heapAdjust(A,0,i);
        }
        return A;
    }

    void buildHeap(int* A, int size_A)
    {
        for (int i = (size_A)/ 2-1; i >= 0; i--)
        {
            heapAdjust(A,i,size_A);
        }
    }

    void heapAdjust(int* A, int root, int size_A) //大顶堆
    {
        int leftchild = 2 * root + 1;
        if (leftchild<size_A) //递归形式
        {
            int rightchild = leftchild + 1;
            if (rightchild<size_A)
            {
                if (A[leftchild]<A[rightchild])
                {
                    leftchild = rightchild;
                }
            }
            //leftchild为左右子节点中较大的结点
            if (A[root]<A[leftchild])
            {
                int temp = A[root];
                A[root] = A[leftchild];   //将较大结点值上移到根节点
                A[leftchild] = temp; //完成交换,子节点变为以前的根节点
                heapAdjust(A, leftchild, size_A);
            }
        }
        return;
    }
};
class HeapSort2 {
public:
    int* heapSort(int* A, int n) {
        // write code here
        buildHeap(A, n); //初始时构建堆
        //从最后一个元素开始对序列进行调整
        for (int i = n - 1; i >= 0; i--)
        {
            swap(&A[0], &A[i]);
            heapAdjust(A, 0, i);
        }
        return A;
    }

    void buildHeap(int* A, int size_A)
    {
        for (int i = (size_A - 1) / 2; i >= 0; i--)
        {
            heapAdjust(A, i, size_A);
        }
    }

    void heapAdjust(int* A, int root, int size_A)  //调整为大顶堆
    {
        int temp = A[root];
        int leftchild = 2 * root + 1;
        while (leftchild < size_A) //非递归形式
        {
            int rightchild = leftchild + 1;
            if (rightchild < size_A)
            {
                if (A[leftchild] < A[rightchild])
                {
                    leftchild = rightchild;
                }
            }
            //leftchild为左右子节点中较大的结点
            if (A[root] < A[leftchild])
            {
                A[root] = A[leftchild];   //将较大结点值上移到根节点
                root = leftchild;         //更新新的根节点
                leftchild = 2 * root + 1;
            }
            else  //当前结点大于左右子节点则不需要调整
            {
                break;
            }
            A[root] = temp; //完成交换,子节点变为以前的根节点
        }
        return;
    }
};

//希尔排序  O(N*log(N)) ---不稳定
class ShellSort {
public:
    int* shellSort(int* A, int n) {
        // write code here
        int dk = n / 2;
        while (dk>=1)
        {
            shellSort2(A,n,dk);
            dk /= 2;
        }
        return A;
    }
    void shellSort(int* A, int n, int dk)
    {
        for (int i = dk; i < n;i++)
        {
            int index = i; //当前访问的位置
            while (index>=dk)
            {
                if (A[index-dk]>A[index])
                {
                    swap(&A[index-dk],&A[index]); //交换不算最优,找到插入位置才交换
                    index -= dk;
                }
                else
                {
                    break;
                }
            }
        }
    }
    void shellSort2(int* A,int n,int dk)
    {
        for (int i = dk; i < n;i++)
        {
            if (A[i]<A[i-dk]) //找到插入位置
            {
                int x = A[i];//复制哨兵
                A[i] = A[i - dk];
                int j = i - dk; //从该位置向前查找
                while (x<A[j]&&j>=0) //防止j越界
                {
                    A[j] = A[j - dk];
                    j -= dk; //向前移动
                }
                A[j + dk] = x;// 插入到正确位置
            }
        }
    }

};

#define N 13
int main()
{
    //待排数据输入方式:
        /*int N = 0;
        cout << "排序数据个数:\n";
        cin >> N;
        int* A = new int[N];
        cout << "请输入待排序的数据:\n";
        for (int i = 0; i < N; i++)
        {
        cin >> A[i];
        }*/
    //数据直接给定
        int B[N] = { 1, 6, 3, 5, 2, 4 };
        int C[13] = { 54, 35, 48, 36, 27, 12, 44, 44, 8, 14, 26, 17, 2 };
        int* A = C;

    //从文件中读取,大量数据,计算时间复杂度

    printResult("待排原始数据:", C, N);

    BubbleSort bubble;
    bubble.bubbleSort(A,N);
    printResult("bubbleSort", A, N);

    SelectionSort select;
    select.selectionSort(A, N);
    printResult("selectSort", A, N);

    InsertionSort insert;
    insert.insertionSort(A, N);
    printResult("InsetSort", A, N);

    MergeSort merge;
    merge.mergeSort(A, N);
    printResult("MergeSort", A, N);

    QuickSort qucik;
    qucik.quickSort(A, N);
    printResult("QucikSort",A,N);

    QuickSort2 qucik2;
    qucik2.quickSort(A, N);
    printResult("QucikSort2", A, N);

    HeapSort heap;
    heap.heapSort(A, N);
    printResult("heapSort", A, N);

    HeapSort2 heap2;
    heap2.heapSort(A, N);
    printResult("heapSort2", A, N);

    ShellSort shell;
    shell.shellSort(A,N);
    printResult("shellSort", A, N);

    return 0;
}
时间: 2024-10-12 20:33:18

排序算法的实现(归并,快排,堆排,希尔排序 O(N*log(N)))的相关文章

探讨排序算法的实现

排序算法是我们工作中使用最普遍的算法,常见的语言库中基本都会有排序算法的实现,比如c标准库的qsort,stl的sort函数等.本文首先介绍直接插入排序,归并排序,堆排序,快速排序和基数排序等比较排序算法,然后介绍计数排序,基数排序等具有线性时间的排序算法.本文主要讨论算法的实现方法,并不会过多介绍基本理论. 评价一个排序算法优劣适用与否,一般需要从三个方面来分析 时间复杂度.用比较操作和移动操作数的最高次项表示,由于在实际应用中最在乎的是运行时间的上限,所以一般取输入最坏情况的下的运行时间作为

Python学习(三) 八大排序算法的实现(下)

本文Python实现了插入排序.基数排序.希尔排序.冒泡排序.高速排序.直接选择排序.堆排序.归并排序的后面四种. 上篇:Python学习(三) 八大排序算法的实现(上) 1.高速排序 描写叙述 通过一趟排序将要排序的数据切割成独立的两部分,当中一部分的全部数据都比另外一部分的全部数据都要小,然后再按此方法对这两部分数据分别进行高速排序,整个排序过程能够递归进行,以此达到整个数据变成有序序列. 1.先从数列中取出一个数作为基准数. 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全

七种排序算法的实现和总结

最近把七种排序算法集中在一起写了一遍. 注释里有比较详细的说明. 1 /*排序算法大集合**/ 2 #include <stdio.h> 3 #include <string.h> 4 #include <stdlib.h> 5 6 //------------------快速排序------------------// 7 /* 8 核心: 9 如果你知道多少人该站你前面,多少人站你后面,你一定知道你该站哪个位置. 10 算法: 11 1.选取分界数,参考这个分界数,

Python 排序算法的实现

冒泡排序: 1 def bubble(l): 2 length = len(l) 3 for i in range(length): 4 for j in range(i+1, length): 5 if l[i] > l[j]: 6 l[i], l[j] = l[j], l[i] 7 print l 选择排序: 1 def select(l): 2 length = len(l) 3 for i in range(length): 4 minn = i 5 for j in range(i+1

#排序算法#【2】直接插入排序、希尔排序

直接插入排序法 插入排序的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入.插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后移动,为最新元素提供插入空间. 核心代码: //直接插入排序法 void InsertSort(int a[],int n){ int i,j,k,t; for(i = 1 ; i<n;i++){ k = a[i]; /* 第一次比较粗糙的写法 j = i-1; while(

软考笔记第六天之各排序算法的实现

对于前面的排序算法,用c#来实现 直接插入排序: 每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序.第一趟比较前两个数,然后把第二个数按大小插入到有序表中: 第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中:依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程.直接插入排序属于稳定的排序,最坏时间复杂性为O(n^2),空间复杂度为O(1).直接插入排序是由两层嵌套循环组成的.外层循环标识并决定待比较的数值.内层循环为待比较数值确定其最终位

各种排序算法的实现和比较

算法的稳定性 如果待排序表中有两个元素 Ri 和 Rj,其对应的关键字keyi = keyj,注意是关键字相等,且在排序前 Ri 排在 Rj 前面,如果使用某一算法排序后,Ri 仍在 Rj 前面,则称这个算法是稳定的,否则是不稳定的. 在排序过程中,根据元素是否完全在内存中,可以将排序算法分为两类:内部排序是指在排序期间元素全部存放在内存中的排序:外部排序是指在排序期间元素无法全部同时放在内存中,必须在排序过程中根据要求不断地在内外存之间移动. 以下所有代码基于此类结构: typedef int

各种排序算法的实现、总结

排序算法 比较排序 2.非比较排序 计数排序.基数排序 排序算法实现 假定序列array[10]={73,22,93,43,55,14,28,65,39,81}  (以升序为例) 直接插入排序 直接插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕. 1 void Insertsort(int* array,size_t n) 2 { 3 assert(array); 4 for (size_t i = 0; i < n-1; i++) 5 { 6 in

各种排序算法的实现代码

#include"stdio.h" #include"malloc.h" #include"stdlib.h" typedef int KeyType; #define MAXSIZE 20 typedef struct { KeyType key; }RedType; typedef struct { RedType r[MAXSIZE+1]; int length; }SqList,* SQLIST; void play_choose(voi