数据结构排序算法

交换类算法:

起泡算法

每次选出一个最大的数字甩到后面,再次选择次大的,...循环下去。

#include <stdio.h>
//起泡排序
void BubbleSort(int R[],int n)
{
    //大的数字往后冒(写小的往前也行)
    int i,j,temp,flag=0;
    //最大循环次数i,同时也用作限定每次内循环次数
    for(i=n-1;i>0;i--)
    {
        //用来判断有无交换的标志flag
        flag=0;
        //每次起泡后,最后的元素一定是最大的且有序的,所以循环次数越来越少
        for (j=1;j<=i; j++)
        {
            //大的数字往后交换
            if(R[j-1]>R[j])
            {
                temp=R[j];
                R[j]=R[j-1];
                R[j-1]=temp;
                flag=1;
            }
        }
        //本轮无交换,则排序结束
        if(flag==0)
            return;
    }
}
int main()
{
    int a[7]{7,43,6,3,2,6,87};
    BubbleSort(a, 7);
    int i;
    for(i=0;i<7;i++)
    {
        printf("%d ",a[i]);
    }
}

快速排序

根据关键字划分子区间,左子区间小于关键字,右子区间大于关键字

#include <stdio.h>
//快速排序
void QuickSort(int R[],int low,int high)
{
    int i=low,j=high;
    int temp;
    if(low<high)
    {
        //选择关键字
        temp=R[low];
        while(i<j)
        {
            //右边的往左扫描
            //往左移动,找到一个比关键字小的,然后交换
            while(j>i&&R[j]>=temp)
                j--;
            //如果重合的话就结束了,所以先判断
            if(i<j)
            {
                R[i]=R[j];
                //交换后往后移
                i++;
            }
            //左边的往右扫描
            //往右移动,找到一个比关键字大的,然后交换
            while(j>i&&R[i]<temp)
                i++;
            //如果重合的话就结束了,所以先判断
            if(i<j)
            {
                R[j]=R[i];
                //交换后往后移
                j--;
            }
        }
        R[i]=temp;
        //i,j重合时结束,将左区间和右区间继续进行快排
        QuickSort(R, low, i-1);
        QuickSort(R, i+1, high);
    }
}
int main()
{
    int a[7]{7,43,62,3,2,6,87};
    QuickSort(a,0,6);
    int i;
    for(i=0;i<7;i++)
    {
        printf("%d ",a[i]);
    }
}

选择类排序

简单选择排序

从头到尾扫描,选出最小的关键字与第一个元素交换,再选择第二个最小的关键字与第二个元素交换,...

(和起泡有点像哈)

#include <stdio.h>
//简单选择排序
void SelectSort(int R[],int n)
{
    int i,j,k;
    //交换三部曲的中间量
    int temp;
    for(i=0;i<n;i++)
    {
        //k为最靠前的未排序的关键字,内循环寻找最小值的起点
        k=i;
        for (j=i+1; j<n; j++) {
            //选择最大值
            if(R[k]>R[j])
                k=j;
        }
        //交换三部曲
        temp=R[i];
        R[i]=R[k];
        R[k]=temp;
    }
}
int main()
{
    int a[7]{7,43,62,3,2,6,87};
    SelectSort(a,6);
    int i;
    for(i=0;i<7;i++)
    {
        printf("%d ",a[i]);
    }
}

堆排序

#include <stdio.h>
//对low到high,进行调整
void Sift(int R[],int low,int high)
{
    //R[j]是R[i]的左孩子
    int i=low,j=2*i;
    int temp=R[i];
    while(j<=high)
    {
        //如果右孩子大,则j指向右孩子
        //本质就是找左右孩子里最大的结点
        if(j<high&&R[j]<R[j+1])
        {
            j++;
        }
        //如果最大结点大于双亲结点
        if(temp<R[j])
        {
            R[i]=R[j];
            //temp继续与原孩子结点的孩子结点继续比较
            i=j;
            j=2*i;
        }
        else
            break;
    }
    //被调整的结点放在最后调整的位置
    R[i]=temp;
}
//堆排序
void heapSort(int R[],int n)
{
    int i;
    int temp;
    for(i=n/2;i>=1;i--)
        Sift(R,i,n);
    //以上所有的结点都符合大顶堆,但是排序还没完成,仅仅完成了建大堆的过程
    //如果只剩下两个结点,顺序是必然的
    for(i=n;i>=2;i--)
    {
        temp=R[1];
        R[1]=R[i];
        R[i]=temp;
        Sift(R, 1, i-1);
    }
}
int main()
{
    //堆从1开始的99999只是占个坑
    int a[8]{99999,7,43,62,3,2,6,87};
    heapSort(a,6);
    int i;
    for(i=1;i<8;i++)
    {
        printf("%d ",a[i]);
    }
}

二路归并排序

#include <stdio.h>
//对low到high,进行调整
void merge(int R[],int low ,int mid,int high)
{
    //临时数组
    int temp[1000];
    int k=low;
    int i=low,j=mid+1;
    //小的先进入temp数组
    for(i=low,j=mid+1;i<=mid,j<=high;)
    {
        if(R[i]<R[j])
        {
            temp[k++]=R[i];
            i++;
        }
        else
        {
            temp[k++]=R[j];
            j++;
        }
            
    }
    //如果某一数组已经全部存完,对应数组直接进入数组
    if(i==mid+1)
        for(;j<=high;j++)
            temp[k++]=R[j];
    else if(j==high+1)
        for(;i<=mid;i++)
            temp[k++]=R[i];
    //将temp的有序数组归还R数组
    for(k=low;k<=high;k++)
        R[k]=temp[k];
}
void mergeSort(int R[],int low,int high)
{
    int i;
    for(i=low;i<=high;i++)
    {
        printf("%d %d %d %d\n",i,R[i],low,high);
    }
    if(low<high)
    {
        
        int mid=(low+high)/2;
        mergeSort(R,low,mid);
        mergeSort(R,mid+1,high);
        //1元组排序合并2元组,2元组排序合并4元组,...
        merge(R,low,mid,high);
    }
}
int main()
{
    int a[7]{71,43,5,3,9,6};
    mergeSort(a, 0, 5);
    int i;
    for(i=0;i<6;i++)
    {
        printf("%d ",a[i]);
    }
}

桶排序

#include <stdio.h>
int pow(int i)
{
    if(i==0)
        return 1;
    if(i==1)
        return 10;
    if(i==2)
        return 100;
    if(i==3)
        return 1000;
    return 1;
}
void tong(int a[100],int n,int sum)
{
    int B[100];
    int i,j,k;
    int flag=0;
    //最高位为n为,本次测试为3位
    for (i=0;i<n;i++)
    {
        //每个数组共十个特征,即0-9
        for(j=0;j<10;j++)
        {
            //对位置进行筛选(本过程直接类似出桶)
            for(k=0;k<sum;k++)
            {
                if((a[k]/pow(i))%10==j)
                    B[flag++]=a[k];
            }
        }
        //更换标志位
        flag=0;
        //更新桶
        for(k=0;k<sum;k++)
        {
            a[k]=B[k];
        }
    }
}
int main()
{
    int a[100]={232,41,34,7,58,9,5,424,145,1};
    tong(a,3,10);
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值