数据结构学习日志(十三)排序算法及具体实现/冒泡排序/插入排序/希尔排序/堆排序/选择排序/归并排序/快速排序/基数排序

在这里插入图片描述
冒泡排序:

void Bubble_Sort(vector<int>& array) {//冒泡排序
    int len = array.size();
    while (len - 1) {
        for (int i = 0; i < len - 1; i++)
            if (array[i] > array[i + 1]) Swap(array[i], array[i+1]);//两两比较,每次将较小值上浮
        len--;
    }
}

插入排序:

void Insertion_Sort(vector<int>& array) {//插入排序
    int len = array.size();
    for (int i = 1; i < len; i++) {
        int t = array[i];
        int j = i-1;
        for (j; j >= 0; j--) {
            if (array[j] > t) array[j + 1] = array[j];//找到array[i]应该在的位置
            else break;
        }
        array[j+1] = t;//插入
    }
}

希尔排序:

void Shell_Sort(vector<int>& array) {//希尔排序
    int d,x=0;//增量序列d=2^x-1
    int len = array.size();
    while (pow(2, x) - 1 < len) x++;
    x--;//获取增量序列最大值
    while (x) {
        d = int(pow(2, x)-1);
        for (int i = d; i < len; i+=d) {
            int t = array[i];
            int j = i - d;
            for (j; j >= 0; j-=d) {
                if (array[j] > t) array[j + d] = array[j];//将间隔为d的子序列排序
                else break;
            }
            array[j + d] = t;
        }
        x--;//取下一个增量直至1
    }
}

选择排序:

void Selection_Sort(vector<int>& array) {
    int len = array.size();
    for (int i = 0; i < len-1; i++)
        for (int j = i+1; j < len; j++)
            if (array[i] > array[j]) 
                Swap(array[i], array[j]);//每次选择最小值交换到未排序序列的首位
}

堆排序:

void Adjust(vector<int>& array, int i,int len) {//最大堆调整
    int t = array[i];//记录待调整值,它的左右子树都是堆
    int nexti;//下一个结点下标
    while ((nexti = 2 * (i+1)-1) <= len-1) {//当不是叶子结点时
        if (nexti == len-1) {
            if (array[nexti] <= t) break;//若只有左儿子且已经为堆
        }
        else if (array[nexti] <= t && array[nexti + 1] <= t) break;//当待调整值大于当前位置的左右儿子值,插入该位置
        else if (array[nexti] < array[nexti + 1]) nexti++;//否则和当前结点较大的儿子结点交换位置
        array[i] = array[nexti];
        i = nexti;
    }
    array[i] = t;//将待调整值插入正确位置形成堆
}
int Delete(vector<int>& array, int len) {//弹出堆顶最大值并返回
    int max = array[0];//记录最大值
    array[0] = array[--len];//将末尾元素放到堆顶
    Adjust(array, 0, len);//调整最大堆
    return max;
}
void Heap_Sort(vector<int>& array) {//堆排序
    int len = array.size();
    for (int i = len - 1; i >= 0; i--) {//将当前数组调整成为最大堆
        if (2 * (i+1)-1 >= len) continue;
        Adjust(array, i, len);
    }
    for (int i = len; i > 0; i--)
        array[i - 1] = Delete(array, i);//将弹出最大值赋给末尾元素实现有序
}

归并排序:

void Merge(vector<int>& array,int* temp, int left, int mid, int right) {//归并
    int i = left;
    int j = mid + 1;
    int t = left;
    while (i != mid + 1 && j != right + 1) {//将两个序列遍历比较,记录较小元素
        if (array[i] <= array[j])
            temp[t++] = array[i++];
        else
            temp[t++] = array[j++];
    }
    while (i <= mid) temp[t++] = array[i++];
    while (j <= right) temp[t++] = array[j++];//将剩余元素加入
    while (left <= right) {//赋值回原数组
        array[left] = temp[left];
        left++;
    }
}
void Merge_Sort(vector<int>& array) {
    int len = array.size();
    int* temp = (int*)malloc(sizeof(int)*len);//开额外存储空间
    int x = 0;
    int d,left,mid,right;
    while ((d = int(pow(2, x))) < len) {//从小单元间隔开始归并
        for (int i = 0; i < len; i += 2 * d) {//依次归并
            left = i;
            if ((mid = i + d - 1) >= len-1) break;//剩余元素不足两个单元序列不进行归并
            if ((right = i + d - 1 + d) >= len) right = len - 1;
            Merge(array,temp,left,mid,right);//归并
        }
        x++;
    }
    free(temp);//释放额外空间
}

快速排序:

void Quick(vector<int>& array, int left, int right) {//快速排序
    int i = left;//左指针
    int j = right - 1;//右指针
    if (left + 1 == right) {//只剩两个元素时
        if (array[left] > array[right]) {
            Swap(array[left], array[right]);
        }
        return;
    }
    while (1) {
        if (array[i] < array[right]) i++;//从左往右找到第一个大于等于主元的元素
        if (array[j] >= array[right]&&j>left) j--;//从右往左找到第一个小于主元的元素
        if (i < j) Swap(array[i], array[j]);//交换
        else break;
    }
    Swap(array[i], array[right]);//将主元放到合适位置
    if (i - 1 > left) Quick(array, left, i - 1);//递归左半边序列
    if (i + 1 < right) Quick(array, i + 1, right);///递归右半边序列
}
void Quick_Sort(vector<int>& array) {//快速排序
    int len = array.size();
    Quick(array, 0, len - 1);
}

基数排序:

void Bucket_Sort(vector<int>& array,int i,int len) {//桶排序
    vector<int> bucket[10];//记录表
    int c = int(pow(10, i));
    for (int x = 0; x < len; x++) {
        int t = (array[x] / c) % 10;
        bucket[t].push_back(array[x]);//依据当前数位的数大小记录
    }
    int k = 0;
    for (int x = 0; x < 10; x++) {//赋值回原数组
        for (vector<int>::iterator it = bucket[x].begin(); it != bucket[x].end(); it++) {
            array[k++] = *it;
        }
    }
}
void Radix_Sort(vector<int>& array) {//基数排序
    int n = 0;
    int max = array[0];
    int len = array.size();
    for (int i = 1; i < len; i++) {//求出最大数
        if (array[i] > max) max = array[i];
    }
    while (max) {//计算最大数位数
        n++;
        max /= 10;
    }
    for (int i = 0; i < n;i++) {//从低位数向上比较进行桶排序
        Bucket_Sort(array, i,len);
    }
}

对一万个数的无序随机数组进行排序测试,得到如下结果:
测试结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值