scau:数据结构oj 实验六

//8638 直接插入排序
#include<iostream>
using namespace std;

int main()
{
    int n;
    cin>>n;
    int a[n];
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=2;i<=n;i++)
    {
        if(a[i]<a[i-1])
        {
            int j;
            a[0]=a[i];
            a[i]=a[i-1];
            for(j=i-2;a[0]<a[j];j--)
            a[j+1]=a[j];
            a[j+1]=a[0];
        }
        int k;//记住j,k要在外面定义
        for(k=1;k<n;k++)
        cout<<a[k]<<" ";
        cout<<a[k]<<endl;
    }
    return 0;
}
//8639 折半插入排序
#include <cstdio>
#include <iostream>
using namespace std;

int main()
{
    int n;cin>>n;
    int a[n];
    for(int i=1;i<=n;i++)
    cin>>a[i];
    for(int i=2;i<=n;i++)
    {
        if(a[i]<a[i-1])
        {
            a[0]=a[i];
            int low=1,high=i-1,mid;

            while(low<=high)
            {
             mid=low+((high-low)>>1);//右移一位相当于除于二,防止溢出
            if(a[mid]>a[0])
            high=mid-1;
            else
            low=mid+1;

            }
            //循环结束之后low=high+1
            //high指向的数字可能小于或者等于a[0]
            for(int j=i;j>low;j--)//low到i的数需要后移
            {
                a[j]=a[j-1];
            }
            a[low]=a[0];
        }

        //一次外层循环结束之后,再打印,不管是否a[i]<a[i-1]
        for(int k=1;k<=n;k++)
        cout<<a[k]<<" ";
        cout<<endl;

    }

    return 0;
}
//8640 希尔(shell)排序
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int n;
    cin>>n;
    int a[n];
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int d=n/2;d>=1;d/=2)
    {
        for(int i=d+1;i<=n;i++)
        {
            if(a[i]<a[i-d])
            {
                int j;
                a[0]=a[i];
                for(j=i-d;a[j]>a[0]&&j>=1;j-=d)//这里是a[j]>a[0]而不是a[j-d]>a[0]
                a[j+d]=a[j];
                a[j+d]=a[0];
            }

        }
        for(int k=1;k<=n;k++)//d变化一次输出一次
            cout<<a[k]<<" ";
            cout<<endl;
    }

    return 0;
}
//8641 冒泡排序
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int n;cin>>n;
    int a[n];
    for(int i=1;i<=n;i++)
    cin>>a[i];
    for(int i=n-1;i>=1;i--)
    //因为有了flag判断是否还需要排列,所以i的初始值需要为j的最大值
    //所以j刚开始循环的时候范围才能从最大开始,之后逐渐缩小范围
    //保证了之后尾部都是有序的
    {//冒泡循环外层循环为n-1次
        int flag=0;
        for(int j=1;j<=i;j++)
        {
            if(a[j]>a[j+1])
            {
                int temp;
                temp=a[j+1];
                a[j+1]=a[j];
                a[j]=temp;
                flag=1;
            }
        }

        for(int k=1;k<=n;k++)
        cout<<a[k]<<" ";
        cout<<endl;
        if(!flag)//要先输出之后再判断flag
        break;
    }
    return 0;
}
//8642 快速排序
#include <iostream>
#include <algorithm>

using namespace std;

int n,a[10000];

int paixu(int a[],int i,int j)
{
    a[0]=a[i];//因为这里取出的是a[i]的值,
    //所以下面循环里面要先比较a[j]>=a[0],让a[i]=a[j];
    while(i<j)//记住这里要用while
    {
        //顺序不能调换,不然是错误的
        while(i<j&&a[j]>=a[0])//不要漏掉i<j的条件
        j--;
        a[i]=a[j];
        while(i<j&&a[i]<=a[0])
        i++;
        a[j]=a[i];
    }
    //循环后i等于j,这里a[i]或者a[j]都可以
    a[i]=a[0];
    return i;
}

void xunhuan(int a[],int i,int j)
{
    if(i<j)
    {
        int k;
        k=paixu(a,i,j);
        for(int p=1;p<=n;p++)
        cout<<a[p]<<" ";
        cout<<endl;
        xunhuan(a,i,k-1);//这里两行分别是i和j,不要搞错了
        xunhuan(a,k+1,j);
    }
}


int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    xunhuan(a,1,n);
    return 0;
}
//8643 简单选择排序
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int n;cin>>n;
    int a[n];
    for(int i=1;i<=n;i++)
    cin>>a[i];
    for(int i=1;i<=n-1;i++)
    {//注意i循环n-1次
        //注意要记录k值,因为后面会改变
        int k=i;
        for(int j=i+1;j<=n;j++)
        {
            if(a[k]>a[j])//这一步是为了找到最小值,然后再交换
            {
                k=j;
            }
        }
            if(k!=i)
            {
                int temp;
                temp=a[k];
                a[k]=a[i];
                a[i]=temp;
            }


        for(int k=1;k<=n;k++)
        cout<<a[k]<<" ";
        cout<<endl;

    }
    return 0;
}
//8644 堆排序
#include <iostream>
#include <algorithm>

using namespace std;

int a[10000],n;

void heapbuilt(int start,int end)//初始构建堆
{
    int dad=start;
    int son=dad*2;
    while(son<=end)
    {
        if(son+1<=end&&a[son]<a[son+1])
        son++;//找到左右孩子中较大的孩子
        if(a[dad]>a[son])//如果大于,说明子树全是大根堆,不需要再交换了,就退出
        return ;
        else
        {
        swap(a[son],a[dad]);//交换,使得父亲节点是最大值
        //因为交换了,所以子树不一定是大根堆,需要再次循环比较
        dad=son;
        son=dad*2;
        }
    }
}


void heapsort()
{
    for(int i=n/2;i>=1;i--)
    heapbuilt(i,n);//这里初始值是最后一个结点,循环依次减小
    for(int k=1;k<=n;k++)
        cout<<a[k]<<" ";
        cout<<endl;
    for(int i=n;i>1;i--)//注意这里不能等于1
    {
        swap(a[1],a[i]);
        heapbuilt(1,i-1);//这里初始值是1是因为只有头部和尾部动了,其他都是有序的
        for(int k=1;k<=n;k++)
        cout<<a[k]<<" ";
        cout<<endl;
    }
}

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    heapsort();
    return 0;
}
//8645 归并排序(非递归算法)
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    int n;
    cin>>n;
    int *a=(int*)malloc(sizeof(int)*(n+1));
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int d=2;d<2*n-1;d=d*2)//d<=2*n-1是因为(n-1)*2小于d<=2*n-1,易错
    {
        for(int i=1;i<n;i=i+d)
        {
            sort(a+i,a+min(i+d,n+1));
            //这里要取较小值是因为虽然规定了i<n,但是不一定能保证i+d<n,会超出比较的范围
            //取了较小值之后就不会超出排序的范围
            //sort 排序的范围是 [first, last),不包含 last 位置的元素。
            //所以是n+1而不是n
        }
        for(int k=1;k<=n;k++)
        cout<<a[k]<<" ";
        cout<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zero_019

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值