排序算法C++

学习目标:

列举了几种常见的排序算法

选择排序:

// 选择排序
void SelectSort(int arr[], int len) {
    for (int i = 0; i < len - 1; i++) {
        int min = i;   //记录最小值
        for (int j = i + 1; j < len; j++) {
            if (arr[min] > arr[j]) {
                min = j;
            }
        }
        if (min != i) {
            swap(arr[min], arr[i]);
        }
    }
}

冒泡排序:

第一种写法:

void BubbleSort(int arr[], int len) {
    for (int i = 0; i < len - 1; i++) {
        bool flag = false;    //标志
        for (int j = len - 1; j > i; j--) {
            if (arr[j - 1] > arr[j]) {
                swap(arr[j - 1], arr[j]);
                flag = true;
            }
        }
        if (flag == false)  //没有交换,则已完成排序
            return;
    }
}

第二种写法:

void BubbleSort(int arr[], int len) {
    for (int i = 0; i < len - 1; i++) {
        bool flag = false;
        for (int j = 0; j < len - 1 - i; j++) {    // 已排好序的
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
                flag = true;
            }
        }
        if (flag == false)
            return;
    }
}

插入排序

不带哨兵

void InsertSort(int arr[], int len) {
    for (int i = 1; i < len; i++) {
        if (arr[i - 1] > arr[i]) {
            int temp = arr[i];
            int j = i - 1;
            for (j; j >= 0 && arr[j] > temp; j--) {
                arr[j + 1] = arr[j];
            }
            arr[j + 1] = temp;   //
        }
    }
}

带哨兵

void InsertSort1(int arr[], int len) {
    for (int i = 2; i <= len-1; i++) {
        if (arr[i - 1] > arr[i]) {
            arr[0] = arr[i];   //第一个元素当哨兵
            int j = i - 1;
            for (j; arr[j] > arr[0]; j--) {  //不用每轮循环都判断j>=0
                arr[j + 1] = arr[j];
            }
            arr[j + 1] = arr[0];
        }
    }
}

折半插入排序

插入排序的改进,用二分法搜索待插入的位置

void HalfInsertSort(int arr[], int len) {
    for (int i = 1; i < len; i++) {
        if (arr[i - 1] > arr[i]) {
            int temp = arr[i];
            int j = i - 1;
            int low = 0;
            int high = i - 1;
            while (low <= high) {
                int mid = (low + high) / 2;
                if (arr[mid] > temp)
                    high = mid - 1;
                else
                    low = mid + 1;
            }
            for (j; j >= high + 1; j--) {
                arr[j + 1] = arr[j];
            }
            arr[j + 1] = temp;
        }
    }
}

希尔排序:

void ShellSort(int arr[], int len) {
    for (int d = len / 2; d >= 1; d = d / 2) {  //步长
        for (int i = d ; i < len; i++) {
            if (arr[i - d] > arr[i]) {
                int temp = arr[i];
                int j = i - d;
                for (j; j >= 0 && arr[j] > temp; j -= d) {
                    arr[j + d] = arr[j];
                }
                arr[j + d] = temp;
            }
        }
    }
}

快速排序:

int Partition(int arr[], int low, int high) {
    int pivot = arr[low];
    while (low < high) {
        while (low < high && arr[high] >= pivot)
            high--;
        arr[low] = arr[high];
        while (low < high && arr[low] < pivot)
            low++;
        arr[high] = arr[low];
    }
    arr[low] = pivot;
    return low;
}

int RandomPartition(int arr[], int low, int high) {
    int ran = rand() % (high - low + 1) + low;
    swap(arr[low], arr[ran]); //随机选取
    return Partition(arr, low, high);
}

void RandomQuickSort(int arr[], int low, int high) {
    if (low < high) {
        int pos = RandomPartition(arr, low, high);
        RandomQuickSort(arr, low, pos - 1);
        RandomQuickSort(arr, pos + 1, high);
    }
}

归并排序:

int* temp = new int[20];  //辅助数组
void Merge(int arr[],int left,int mid,int right){
    int i = left;
    int j = mid + 1;
    int k = left;
    for (int q = left; q <= right; q++) {
        temp[q] = arr[q];
    }
    while (i <= mid && j <= right) {
        if (temp[i] <= temp[j])
            arr[k++] = temp[i++];
        else
            arr[k++] = temp[j++];
    }
    while (i <= mid) {
        arr[k++] = temp[i++];
    }
    while (j <= right) {
        arr[k++] = temp[j++];
    }
}

void MergeSort(int arr[], int left, int right) {
    if (left < right) {
        int middle = (left + right) / 2;
        MergeSort(arr,  left, middle);
        MergeSort(arr,  middle + 1, right);
        Merge(arr,  left, middle, right);
    }
}

堆排序

void Adjust(int arr[], int index, int len) {  //将index为根的子树调整为大根堆
    int temp = arr[index];
    for (int i = 2 * index+1; i < len; i = 2*i+1) {
        if (i < len-1 && arr[i] < arr[i + 1]) {
            i++;
        }
        if (temp >= arr[i])
            break;
        else {
            arr[index] = arr[i];
            index = i;
        }
    }
    arr[index] = temp;
}

void HeapSort(int arr[], int len) {
    for (int i = len / 2 - 1; i >= 0; i--) {
        Adjust(arr, i, len); //构建大顶堆
    }
    for (int i = len - 1; i >= 1; i--) {
        swap(arr[i], arr[0]);  //堆底堆顶互换
        Adjust(arr, 0, i);     //重新构建大顶堆
    }
}

计数排序

void CountSort1(int arr[], int len) {
    int max = arr[0];
    int min = arr[0];
    for (int i = 1; i < len; i++) {
        if (arr[i] > max)
            max = arr[i];
        if (arr[i] < min)
            min = arr[i];
    }
    int *ret=new int [max-min+1]();  //区间
    for (int i = 0; i<len; i++) {
        ret[arr[i]-min]++;
    }
    int count = 0;  //计数
    for (int i = 0; i < max - min + 1; i++) {
        for (int j = ret[i]; j > 0; j--) {
            arr[count++] = i+min;
        }
    }
}

基数排序

void Distribute(vector<int>& nums, vector<vector<int>>& rr,int p) {
    for (int i = 0; i < nums.size(); i++) {
        rr [9 + (int)(nums[i] / pow(10, p)) % 10] .emplace_back(nums[i]);   //放到对应桶里
        
    }
}
void Collect(vector<int>& nums, vector<vector<int>>& rr) {
    int count = 0;
    for (int i = 0; i < rr.size(); i++) {
        for (int j = 0; j < rr[i].size(); j++) {
            nums[count++] = rr[i][j];  //回收
        }
        rr[i].clear();
    }
}
void RadixSort(vector<int>& nums) {
    vector<vector<int> >res(19, vector<int>(0));//19个桶
    int mx = abs(nums[0]);
    for (int i = 1; i < nums.size(); i++) {
        mx = max(mx, abs(nums[i]));  //绝对值最大
    }
    int p = mx == 0 ? 0 : (log(mx) / log(10));
    for (int i = 0; i <= p; i++) {
        Distribute(nums, res,i);
        Collect(nums, res);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值