【Algorithm】c++实现各种排序算法

学习中。。。

#include <iostream>

#define SIZE 10

using namespace std;

void print(int arr[], int n){
    for (int i = 0; i < n; i++)
        cout << arr[i] << ' ';
    cout << endl << endl;
}

void Swap(int &a, int &b){
    a += b;
    b = a - b;
    a -= b;
}
/*
冒泡排序:持续比较相邻两个数最多n趟
最好   最坏     平均     空间   稳定性 复杂性
O(n)   O(n^2)   O(n^2)   O(1)    稳定    简单
*/
void bubbleSort(int arr[], int n){
    for (int i = 0; i < n - 1; i++){
        int exchange = 0;
        for (int j = 0; j < n - 1; j++)
        if (arr[j] > arr[j + 1]){//升序     (arr[j] > arr[j + 1])//降序
            Swap(arr[j], arr[j + 1]);
            exchange++;
        }
        if (exchange == 0)  //如果某一趟一次也没有交换,则说明已经是一个有序序列
            break;
    }
}

/*
堆排序:构造大(降序)/小(升序)顶堆,
最好        最坏        平均        空间    稳定性   复杂性
O(nlog2n)   O(nlog2n)   O(nlog2n)   O(1)    不稳定    较复杂
*/

//该函数用于判断当前节点是否有左右子树,以及有必要的话交换当前节点与左右子节点中较小的那个
void heapSwap(int arr[],int root,int n){
    int left = 2 * root + 1;
    int right = 2 * (root + 1);
    if (right <= n){  //存在右节点,必定有左节点(完全二叉树)
        int min = arr[left] < arr[right] ? left : right;     //选出较小的放到顶上,再插到最后,降序
        if (arr[root] > arr[min]) //根节点较大,交换
            Swap(arr[root], arr[min]);
    }
    else if (left <= n)  //如果右节点大于n,而存在左节点的话
        if (arr[root] > arr[left])
            Swap(arr[root], arr[left]);

}

void heapAdjust(int arr[], int root, int n){/*待排数据,当前根节点索引,数组长度*/
    heapSwap(arr, root, n);  //交换根节点与较小节点
    int left = root * 2 + 1;
    int right = root * 2 + 2;
    if (left <= n)
        heapAdjust(arr, left, n);   //递归调整左子树
    if (right <= n)
        heapAdjust(arr, right, n);   //递归调整右子树,如果有的话
    heapSwap(arr, root, n);    //调整之后再交换根节点与左右子树,因为有可能调整之后左右子树又比根节点小了

}
void heapSort(int arr[], int n){
    for (int i= n-1; i >0; i--){
        heapAdjust(arr, 0, i);//调整为小顶堆
        Swap(arr[i], arr[0]);  //交换顶元素和最后一个元素
    }
}

/*
选择排序:每次从未排序的数组中找出最大(降序)或最小(升序)的元素与未排序数组最前面的元素交换
最好     最坏     平均     空间    稳定性   复杂性
O(n^2)   O(n^2)   O(n^2)   O(1)    不稳定    较简单

*/

void selectionSort(int arr[], int n){
    for (int i = 0; i < n; i++){
        int min = i;
        for (int j = i; j < n-1; j++){
            if (arr[j + 1]<arr[j])     //升序
                min = j + 1;
            if (min != i)
                Swap(arr[min], arr[i]);
        }
    }
}


/*
插入排序:将为排序的数组中下一个数插入到已排序序列的适当位置。
最好     最坏     平均     空间    稳定性   复杂性
O(n)     O(n^2)   O(n^2)   O(1)    稳定      较简单

*/

void insertionSort(int arr[], int n){
    for (int i = 1; i < n; i++){
        int tmp = arr[i];
        int j = 0;
        for (j = i - 1; j >= 0; j--)
            if (arr[j] < tmp)   //降序
                arr[j + 1] = arr[j];
        arr[++j] = tmp;
    }
}

/*
快速排序:挖坑填数
最好         最坏     平均       空间      稳定性     复杂性
O(nlogn)     O(n^2)   O(nlogn)   O(1)      不稳定      较简单

*/
void quickSort(int arr[], int n, int l, int r){
    if (l > r)
        return;
    int i = l, j = r, key = arr[i];
    while (i < j){
        while (i<j&&arr[j]>=key)
            j--;
        if (i < j){
            arr[i] = arr[j];
            i++;
        }
        while (i < j&&arr[i] < key)
            i++;
        if (i < j){
            arr[j] = arr[i];
            j--;
        }
        arr[i] = key;
        quickSort(arr, n, l,i-1);
        quickSort(arr, n, i+1, r);
    }
}





int main(){
    int arr1[SIZE] = { 1, 2, 3, 5, 6, 4, 7, 9, 8, 0 };
    int arr2[SIZE] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    cout << "源数组:" << endl;
    print(arr1, SIZE);
    //冒泡排序:升序
    bubbleSort(arr1, SIZE);
    cout << "冒泡排序:升序" << endl;
    print(arr1, SIZE);
    //堆排序:降序
    cout << "堆排序:降序" << endl;
    heapSort(arr1, SIZE);
    print(arr1, SIZE);
    //选择排序:升序
    cout << "选择排序:升序" << endl;
    selectionSort(arr1, SIZE);
    print(arr1, SIZE);
    //插入排序:降序
    cout << "插入排序:降序" << endl;
    insertionSort(arr1, SIZE);
    print(arr1, SIZE);
    //快速排序:升序
    cout << "快速排序:升序" << endl;
    quickSort(arr1, SIZE, 0, SIZE-1);
    print(arr1, SIZE);


    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值