排序算法代码与总结

一、插入排序

1.直接插入排序

#include <iostream>
using namespace std;

//直接插入排序
void InsertSort(int A[],int n)
{
    int i,j,temp;
    for(int i = 1; i< n ; i++)//将各元素插入已排好序的子序列中
    {
        if(A[i] < A[i-1])//若当前元素小于前一个元素,则交换它们
        {
            temp = A[i];
            for(j = i - 1;j >= 0 && A[j] > temp; --j)  //检查所有前面已安排好排序的元素
                A[j+1] = A[j];    //所有大于temp的元素都向后挪位
            A[j+1] = temp;  //插入到插入位置
        }
    }
}

2.折半插入排序

//折半插入排序
void InsertSort(int A[],int n)
{
    int i,j,low,high,mid;
    for(i = 2;i<=n;i++)      //依次将A[2] ~ A[n]插入前面的已排序序列
    {
        A[0] = A[i];   //将A[i]暂存到A[0]
        low = 1;high = i-1; //设置折半查找的范围
        while(low <= high){  //折半查找(默认递增有序)
            mid = (low+high)/2; //取中间点
            if(A[mid] > A[0]) high = mid -1;//查找左半子表
            else low = mid+1;  //查找右半子表
        }
        for(j = i-1;j >= high+1;--i)
            A[j+1] = A[j];    //统一后移元素,空出插入位置
        A[high+1] = A[0];
    }
}

在这里插入图片描述

3.希尔排序

//希尔排序
void ShellSort(int A[],int n)
{
    //A[0]只是暂存单元,不是哨兵,当j <= 0时,插入位置已到
    int d,i,j;
    for(d = n/2;d >= 1;d = d/2) //步长变化
        for(i = d+1;i <= n;i++)
        {
            if(A[i] < A[i-d])
            {
                A[0] = A[i];
                for(j = i-d;j > 0&& A[0] < A[j];j -=d)
                {
                    A[j+d] = A[j];
                }
                A[j+d] = A[0];
            }
        }
}

在这里插入图片描述

二、交换排序

1.冒泡排序

void BubbleSort(int arr[], int n) {
    int i,j;
    for(i =0;i<n;i++)
    {
        for(j = 0;j<n-i;j++)
        {
            if(arr[j] > arr[j+1])
            {
                swap(arr[j],arr[j+1]);
            }
        }
    }
}

在这里插入图片描述

2.快速排序

/用第一个元素将待排序序列划分成左右两个部分
int Partition(int arr[],int low,int high)
{
    int pivot = arr[low];    //选取第一个元素作为基准
    while(low<high)          //用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;           //返回枢轴的位置
}

//快速排序
void QuickSort(int arr[],int low,int high)
{
    if(low<high)   //递归跳出的条件
    {
        int pivotpos = Partition(arr,low,high);  //划分
        QuickSort(arr,low,pivotpos-1);    //对左子表递归排序
        QuickSort(arr,pivotpos+1,high);   //对右子表递归排序
    }
}

在这里插入图片描述

三、选择排序

1.简单选择排序

void selectSort(int arr[], int n) {
    for(int i = 0;i<n-1;i++)//一共进行了n-1趟
    {
        int min = i; //记录最小元素的位置
        for(int j = i+1;j<n;j++)
        {
            if(arr[j] < arr[min])
                min = j;
        }
        if(min != i)//如果最小元素不是当前位置的元素,则交换
        {
            swap(arr[i],arr[min]);
        }
    }
}

在这里插入图片描述

2.堆排序

//建立大根堆的堆排序
void BuildMaxHeap(int A[],int len);
void HeadAdjust(int A[],int k,int len);
void HeapSort(int A[],int len);

//建立小根堆的堆排序
void BuildMaxHeap1(int A[],int len);
void HeadAdjust1(int A[],int k,int len);
void HeapSort1(int A[],int len);

//建立大根堆
void BuildMaxHeap(int A[],int len)
{
    for(int i = len/2;i>0;i--)
        HeadAdjust(A,i,len);
}

//将以k为根的子树调整为大根堆
void HeadAdjust(int A[],int k,int len)
{
    A[0] = A[k];      //A[0]暂存子树的根节点
    for(int i = k*2;i<=len;i *= 2)  //沿key较大的子节点向下筛选
    {
        if(i<len && A[i]<A[i+1])
            i++;        //选择key较大的子节点
        if(A[0]>=A[i])
            break;
        else
        {
            A[k] = A[i];   //将A[i]调整到双亲结点上
            k = i;         //修改k值,以便继续向下筛选
        }
    }
    A[k] = A[0];          //被筛选结点的值放入最终位置
}



//堆排序的完整逻辑
void HeapSort(int A[],int len)
{
    BuildMaxHeap(A,len);  //初始建堆
    for(int i = len;i > 1;i--)  //n-1趟的交换和建堆过程 
    {
        swap(A[i],A[1]);   //堆顶元素和堆底元素交换
        HeadAdjust(A,1,i-1);  //把剩余的待排序元素整理成堆
    }
}

在这里插入图片描述

在这里插入图片描述

四、归并排序于基数排序

1.归并排序

//A[low...mid]和A[mid+1...high]各自有序,将两个部分归并
void Merge(int A[],int low,int mid,int high)
{
    int i,j,k;
    for(k = low;k <= high;k++)
    {
        B[k] = A[k];  //将A中所有元素复制到B中
    }
    for(i = low,j = mid + 1,k =i;i <= mid && j <=high;k++)
    {
        if(B[i] <= B[j]) A[k] = B[i++];
        else A[k] = B[j++];
    }
    while(i <= mid) A[k++] = B[i++];
    while(j <= high) A[k++] = B[j++];
}

void MergeSort(int A[],int low,int high)
{
    if(low <high)
    {
        int mid = (low + high) / 2; //从中加划分
        MergeSort(A,low,mid); //从左半部分归并排序
        MergeSort(A,mid+1,high); //从右半部分归并排序
        Merge(A,low,mid,high); //归并两个有序部分
    }
}

在这里插入图片描述

2.基数排序

// 获取数组中最大的数字
int getMax(vector<int>& arr) {
    int max = arr[0];
    for (int i = 1; i < arr.size(); i++) {
        if (arr[i] > max)
            max = arr[i];
    }
    return max;
}

// 使用计数排序根据位数进行排序
void countSort(vector<int>& arr, int exp) {
    int n = arr.size();
    vector<int> output(n), count(10, 0);

    // 统计每个数字出现的次数
    for (int i = 0; i < n; i++)
        count[(arr[i] / exp) % 10]++;

    // 累加统计数组
    for (int i = 1; i < 10; i++)
        count[i] += count[i - 1];

    // 从原始数组构建输出数组
    for (int i = n - 1; i >= 0; i--) {
        output[count[(arr[i] / exp) % 10] - 1] = arr[i];
        count[(arr[i] / exp) % 10]--;
    }

    // 将输出数组复制回原始数组
    for (int i = 0; i < n; i++)
        arr[i] = output[i];
}

// 基数排序函数
void radixSort(vector<int>& arr) {
    int max = getMax(arr);

    // 对每一位进行计数排序
    for (int exp = 1; max / exp > 0; exp *= 10)
        countSort(arr, exp);
}

在这里插入图片描述

五、外部排序

1.外部排序

在这里插入图片描述

2.败者树

在这里插入图片描述

3.置换-选择排序

在这里插入图片描述

4.最佳归并树

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值