C++排序算法

2023/11/13 C++ 共 7127 字,约 21 分钟
闷骚的程序员
#include<iostream>
#include<vector>
using namespace std;
//void swap(int &a, int &b);
void printnum(vector<int>& num) {
    for (auto i:num)
        cout << i << " ";

    cout << endl;
}

/*****************************************冒泡排序*********************************/
//冒泡排序-每一轮确定最小的元素
void swap(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}
void bubblesort(vector<int>&num) {
    int length = num.size();
    for (int i = 0; i < length-1; i++) {
        int index = i;
        for (int j = index+1; j < length; j++) {
            if (num[index] > num[j]) {
                swap(num[index], num[j]);
            }

        }
    }
}
//冒泡排序-每一轮确定最大元素
void bubblesort1(vector<int>& num) {
    int length = num.size();
    for (int i = 0; i < length-1; i++) {

        for (int j = 0; j < length-1-i; j++) {
            if (num[j] > num[j+1]) {
                swap(num[j], num[j+1]);
            }

        }
    }
}
//冒泡排序,如果某次排序中未存在交换元素,则说明有序
void bubblesort2(vector<int>& num) {
    int length = num.size();
    bool iswap=true;
    for (int i = 0; i < length - 1; i++) {
        if (!iswap)
            break;
        for (int j = 0; j < length - 1 - i; j++) {
            if (num[j] > num[j + 1]) {
                swap(num[j], num[j + 1]);
                iswap = true;
            }
            else {
                iswap = false;
            }
        }
    }
}
/*****************************************end*********************************/

/*****************************************选择排序*********************************/
//选择排序,将元素与第一位元素比较,找出最大或最小元素,记录其下标,交换位置,完成一次排序。
void selectsort(vector<int>& num) {
    int length = num.size();
    for (int i = 0; i < length; i++) {
        int min = i;
        for (int j = i+1; j < length; j++) {
            if (num[min] > num[j]) {
                min = j;
            }
        }
        swap(num[i], num[min]);        
    }
}
/*****************************************end*********************************/
/*****************************************插入排序*********************************/
//插入排序,在一个已经有序的元素序列中,一次插入一个元素。
void insertsort(vector<int>& num) {
    int length = num.size();
    for (int i = 1; i < length; i++) {
        if (num[i] <  num[i - 1]) {
            int x = num[i];//设置哨兵
            int j = i - 1;
            while (j >= 0 && num[j] > x) {
                //将元素往后移位
                num[j+1] = num[j];
                j--;
            }
            //因为j--了,所以要+1.
            num[j+1] = x;        
        }    
    }
}
//错误的,为体现插入排序的思想。存在了交换
void insertsort2(vector<int>& num) {
    int n = num.size();
    for (int i = 1; i < n; i++) {
        if (num[i] < num[i - 1]) {
            int x = i;
            int j = i-1;
            while (j >= 0 && num[j] > num[x]) {
                //采用交换的方式,但要注意交换后元素的下标变化
                swap(num[j], num[x]);
                x = j;
                j--;
            }
        }    
    }
}
/*****************************************end*********************************/

/*****************************************快速排序*********************************/
//递归方法-hoare法
void quicksort(vector<int>& num,int low,int high) {
    if (low >= high) {
        return;
    }
    int first = low;
    int last = high;
    int key = low;
    while (first < last) {
        //从后往前找第一个比key小的元素
        while (first<last && num[last]>=num[key]) {
            last--;        
        }
        //从前往后找第一个比key大的元素
        while (first < last && num[first] <= num[key]) {
            first++;    
        }
        //交换两个元素
        swap(num[last], num[first]);
    }
    //当first=last时,说明此位置就是key的正确位置
    swap(num[key], num[first]);
    key = first;
    //
    quicksort(num, low, key - 1);
    quicksort(num, key + 1, high);
}
//挖坑法
void quicksort2(vector<int>& num, int low, int high) {

    //结束递归的条件
    if (low >= high) {
        return;
    }
    int first = low;
    int last = high;
    int key = num[low];
    while (first < last) {
        //从后往前找比key小的元素
        while (first<last && num[last]>=key) {
            last--;
        }
        num[first] = num[last];
        while (first < last && num[first] <= key) {
            first++;
        }
        num[last] = num[first];
    }
    num[last] = key;

    quicksort2(num, low, first - 1);
    quicksort2(num, first + 1, high);

}
/*****************************************end*********************************/

/*****************************************希尔排序*********************************/
//每一趟以一组为单位,将每个分组都变得有序
void shellsort1(vector<int>& num) {
    int len = num.size();
    //外层循环,确定分组个数,并逐渐减少分组
    for (int gap = len / 2; gap > 0; gap /= 2) {
        //遍历每个分组
        for (int i = 0; i < gap; i++) {
            //每个分组内进行插入排序
            for (int j = i + gap; j < len; j += gap) {
                int k = j - gap;
                int temp = num[j];
                if (num[j] < num[j - gap]) {    
                    while (k >= 0 && num[k] > temp) {
                        num[k + gap] = num[k];
                        k -= gap;
                    }
                }
                num[k + gap] = temp;

            }
        }

    }
}
//网上实例代码--每一趟排序所有分组中的一小部分元素
void shellSort(std::vector<int>& arr) {
    int n = arr.size();

    // 开始间隔的大小
    for (int gap = n / 2; gap > 0; gap /= 2) {
        // 对每个间隔gap进行插入排序,-----不明白
        for (int i = gap; i < n; ++i) {
            //插入排序
            int temp = arr[i];
            int j;
            // 将arr[i]插入到已经排序的子数组中
            for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
                arr[j] = arr[j - gap];
            }
            arr[j] = temp;
        }
    }
}
/*****************************************end*********************************/
/*****************************************归并排序*********************************/
void mergesort(vector<int>& num,vector<int>& numtemp,int low,int high) {
    if (low >= high) {
        return;
    }
    //分组
    int left = low;
    int right = high;
    int mid = (left + right) / 2;
    int start1 = left;
    int end1 = mid;
    int start2 = mid + 1;
    int end2 = right;
    mergesort(num, numtemp,start1, end1);
    mergesort(num, numtemp,start2, end2);
    //合并
    int index = low;
    //当两个半区都有元素时
    while (start1 <= end1 && start2 <= end2) {
        numtemp[index++] = num[start1] < num[start2] ? num[start1++] : num[start2++];
    }
    //当左半区没有元素时
    while (start2 <= end2) {
        numtemp[index++] = num[start2++];
    }
    while (start1 <= end1) {
        numtemp[index++] = num[start1++];
    }
    //将合并后的数组复制到原数组
    while (left <= right) {
        num[left] = numtemp[left];
        left++;
    }    
}
void mergeSort2(vector<int>& num, int left, int right) {
    //终止条件
    if (left >= right) {
        return;
    }
    //先分组
    int low = left;
    int high = right;
    int mid = (low + high) / 2;
    mergeSort2(num, low, mid);
    mergeSort2(num, mid + 1, high);
    //再合并
    int start1 = low, end1 = mid, start2 = mid + 1, end2 = high;
    //创建一个临时数组
    int len = high - low+1;
    //临时数组的首元素
    int key = 0;
    vector<int>*temp = new vector<int>(len);
    //将两个半区的数组合成一个数组,将结果放到临时数组里面
    //两个半区都有元素时
    while (start1 <= end1 && start2 <= end2) {
        (*temp)[key++] = num[start1] < num[start2] ? num[start1++] : num[start2++];
    }
    while (start1 <= end1) {
        (*temp)[key++] = num[start1++];
    }
    while (start2 <= end2) {
        (*temp)[key++] = num[start2++];
    }
    //将临时数组赋值到原数组中
    for (int i = 0; i < (*temp).size(); i++) {
        num[i+left] = (*temp)[i];
    }
    delete temp;
}
/*****************************************end*********************************/
/*****************************************堆排序*********************************/
//num-待维护的数组,n-数组的长度,i-待维护的节点
void headity(vector<int>& num, int n, int i) {
    int node = i;
    int left = i * 2 + 1;
    int right = i * 2 + 2;
    if (right<n && num[right]>num[node]) {
        node = right;
    }
    if (left<n && num[left]>num[node]) {
        node = left;
    }
    if (node != i) {
        swap(num[node], num[i]);
        headity(num, n, node);
    }
}
void headsort(vector<int>& num) {
    //建堆,找到第一个非叶子节点
    int len = num.size();
    int i;
    for (i = len / 2 - 1; i >= 0; i--) {
        headity(num, len, i);
    }
    //排序
    for (int j = len-1; j >= 0; j--) {
        swap(num[j], num[0]);
        headity(num, j, 0);
    }
}
/*****************************************end*********************************/
/*****************************************计数排序*********************************/
void countsort(vector<int>& num) {
    //计数数组
    //1找到待排序数组中的最大值,创建计数数组大小为最大值+1;
    int len = num.size();
    int max=num[0];
    for (int i = 1; i < len; i++) {
        if (max < num[i]) {
            max = num[i];
        }
    }
    vector<int>countnum(max + 1,0);
    for (int j = 0; j < len; j++) {
        countnum[num[j]]++;
    }
    //累积数组
    for (int k = 1; k < max+1; k++) {
        countnum[k] += countnum[k - 1];
    }
    vector<int>result(len, 0);
    for (int l = 0; l < len; l++) { 
        result[countnum[num[l]] - 1] = num[l];
        countnum[num[l]]--;
    }
    //将结果复制到原数组中
    num = result;
}
/*****************************************end*********************************/
int main() {
    vector<int>my_num = {8,9,1,4,2,3,6,7,5,5};
    ////冒泡排序
    //bubblesort(my_num);
    ////选择排序
    //selectsort(my_num);
    //插入排序
    /*insertsort(my_num);*/
    //快速排序
    /*quicksort(my_num, 0, my_num.size()-1);*/
    //希尔排序
    /*shellsort(my_num);*/
    /*shellsort1(my_num);*/
    //归并排序
    //vector<int>num(my_num);
    //mergesort(my_num, num, 0, my_num.size() - 1);
    /*mergeSort2(my_num, 0, my_num.size() - 1);*/
    /*headsort(my_num);*/
    countsort(my_num);
    printnum(my_num);
    return 0;
}

文档信息

Search

    Table of Contents