2022王道数据结构之顺序表课后题

顺序表课后题

废话不多说,直接上代码,记录一下

#include <iostream>
using namespace std;
#define InitSize 10
typedef struct ArrayList{
    int *data; //指向当前数组的指针,也就是数组的首地址
    int maxSize; //规定数组最大的容量
    int lenth; //数组当前包含元素个数
}Arr;


/**
 * 插入操作
 * @param arr
 * @param position
 * @param content
 * @return
 */
bool insertArr(Arr &arr, int position,int content){
    if(position<1||position>arr.lenth+1)
        return false;
    if(arr.lenth==arr.maxSize)return false;
    for(int j=arr.lenth;j>=position;j--){
        arr.data[j]=arr.data[j-1];
    }
    arr.data[position-1]=content;
    arr.lenth++;
    return true;
}


/**
 * 删除操作
 * @param arr
 * @param position
 * @param e
 * @return
 */
bool deleteArr(Arr &arr, int position,int &e){
    if(position>arr.lenth||position<1){
        return false;
    }

    e=arr.data[position-1];
    for(int j=position-1;j<arr.lenth-1;j++)
        arr.data[j]=arr.data[j+1];
    arr.lenth--;

}

/**
 * 删除数组中所有值为x的元素
 * @param arr
 * @param x
 * @return
 */
bool deleteValueEqX(Arr &arr,int x){
    for(int i=0;i<arr.lenth;i++)
        if(arr.data[i]==x){deleteArr(arr,i+1,x);--i;}

}

/**
 * 逆置数组
 * @param arr
 */
void revertArr(Arr &arr,int m,int n){
    int i=m-1;int j=n-1;int temp;
    for(;i<j;i++,j--){
        temp=arr.data[i];
        arr.data[i]=arr.data[j];
        arr.data[j]=temp;
    }
}

/**
 * 删除顺序表中元素值在s~t间的元素
 * @param arr
 * @param s
 * @param t
 * @return
 */
bool deleteScale(Arr &arr,int s,int t){
    int k=0;//记录数组中范围在s~t间的元素个数
    if(arr.lenth==0||s>t)return false;
    for(int i=0;i<arr.lenth;i++){
        if(arr.data[i]>s&&arr.data[i]<t)k++;
        else arr.data[i-k]=arr.data[i];
    }
    arr.lenth-=k;
    return true;

}

/**
 * 查找两个等长数组的中位数
 * 时间复杂度O(n1+n2),空间复杂度O(1)
 * @param arr1
 * @param arr2
 * @return
 */
int SearchMiddle1(Arr &arr1,Arr &arr2){
    int i=0;int j=0;int k=0;
    while(k<arr1.lenth+arr2.lenth)
    {
        if(arr1.data[i]<arr2.data[j])
        {
            k++;
            if(k==(arr1.lenth+arr2.lenth)/2)return arr1.data[i];
            i++;}
        else {
            k++;
            if(k==(arr1.lenth+arr2.lenth)/2)return arr2.data[j];
            j++;
        }
    }
}

/**
 * 查找两个等长数组的中位数
 * 时间复杂度O(logn),空间复杂度O(1)
 * @param arr1
 * @param arr2
 * @return
 */
int SearchMiddle2(Arr &arr1,Arr &arr2) {
    int s1=0,e1=arr1.lenth-1,m1,s2=0,e2=arr2.lenth-1,m2;
    while(s1!=e1||s2!=e2){
        m1=(s1+e1)/2;m2=(s2+e2)/2;
        //如果两个中位数相等,则该值就是两数组的中位数
        if(arr1.data[m1]==arr2.data[m2])return arr1.data[m1];

        //如果m1<m2,舍弃arr1的m1左侧部分,arr2的m2的右侧部分,因为这些元素不可能成为中位数
        else if(arr1.data[m1]<arr2.data[m2]){

            //如果数组长度为偶数,连中间点一起舍弃
            if((e1+s1)%2==1)
            {s1=m1+1;e2=m2;}
            else {s1=m1;e2=m2;}
        }
        //同上
        else{
            if((e2+s2)%2==0)
            {e1=m1;s2=m2;}
            else
            {
                e1=m1;s2=m2+1;
            }

        }
    }
    if(arr1.data[s1]<arr2.data[s2])return arr1.data[s1];
    else return arr2.data[s2];
}

/**
 * 寻找主元素
 * 时间复杂度O(n),空间复杂度O(1)
 * @param arr
 * @return
 */
int SearchMainElement(Arr &arr){
    int c=arr.data[0];//保存候选主元素
    int num=1;//记录出现次数
    for(int i=1;i<arr.lenth-1;i++){
        if(arr.data[i]==c)++num;
        else {
            if (num > 0)--num;
            else {
                c = arr.data[i];
                num = 1;
            }
        }
    }
    if(num>0){
        num=0;
        for(int i=0;i<arr.lenth;i++){
            if(arr.data[i]==c)++num;
        }
        if(num>arr.lenth/2)return c;
        else return -1;
    }
    else return -1;
}
int getOne(Arr &arr,int el){
    for(int i=0;i<arr.lenth;i++){
        if(arr.data[i]==el)return i+1;
    }
    return -1;
}

/**
 * 合并两个有序数组
 * @param arr1
 * @param arr2
 * @return
 */
bool CombineArrs(Arr &arr1,Arr &arr2,Arr &newArr){
    int i=0;int j=0;//两个flag分别指向两个数组
    int k=0;
    if(arr1.lenth+arr2.lenth>newArr.lenth)return false;
    while(i<arr1.lenth&&j<arr2.lenth){
        if(arr1.data[i]<arr2.data[j])
            newArr.data[k++]=arr1.data[i++];
        else
            newArr.data[k++]=arr2.data[j++];

    }
    while(i<arr1.lenth){
        newArr.data[k++]=arr1.data[i++];
    }
    while(j<arr2.lenth){
        newArr.data[k++]=arr2.data[j++];
    }
}

/**
 * 交换一个数组中的两个子数组位置
 * @param arr
 * @param m 第一个子数组元素个数
 * @param n 第二个子数组元素个数
 * @return
 */
bool ExChangeSubArr(Arr &arr,int m,int n){
    revertArr(arr,1,m);
    revertArr(arr,m+1,m+n);
    revertArr(arr,1,m+n);
}

/**
 * 二分查找
 * @param arr
 * @param x
 * @return
 */
int Dichotomous(Arr &arr,int x){
    int l=0;int r=arr.lenth-1;int flag;
    while(l<r){
        flag=(l+r)/2;
        if(arr.data[flag]==x)return flag;
        if(x<arr.data[flag])r=flag-1;
        else l=flag+1;
    }
}

/**
 * 获取数组中未出现的最小整数
 * 时间复杂度O(n),空间复杂度O(n)
 * @param arr
 * @return
 */
int getSmallestAbsentNum(Arr &arr){
    int *b =new int[arr.lenth];
    for(int i=0;i<arr.lenth;i++){
        if(arr.data[i]>0&&arr.data[i]<=arr.lenth){
            b[arr.data[i]-1]=1;
        }
    }
    int j=0;
    for(;j<arr.lenth;j++){
        if(b[j]==0)break;
    }
    return j;
}
/**
 * 打印数组
 * @param arr
 */
void print(Arr &arr){
    for(int i=0;i<arr.lenth;i++)
        cout<<arr.data[i]<<" ";
    cout<<endl;
}


int main() {
    Arr arr;
    //创建一个数组空间
    arr.data=new int[9]{1,1,2,3,4,24,5,2,6};
    arr.lenth=9;
//    //初始化数组
//    for(int i=0;i<10;i++)
//        arr.data[i]=i+1;
//    arr.lenth=10;
    cout<<"初始数组:";
    print(arr);
    //插入操作
    insertArr(arr,3,17);
    cout<<"插入后数组:";
    print(arr);

    //删除操作
    int e;
    deleteArr(arr,2,e);
    cout<<"删除元素位置为2其值为:"<<e<<"后 "<<"数组变为:";
    print(arr);
    cout<<"位置为3的元素值为:"<<getOne(arr,3)<<endl;

    //删除所有值为x的元素
    deleteValueEqX(arr,1);
    cout<<"删除掉所有元素值为1后的数组:";
    print(arr);

    //逆置数组
    revertArr(arr,1,arr.lenth);
    cout<<"逆置后的数组:";
    print(arr);

    //删除数组中元素值在s~t间的元素
    int result= deleteScale(arr,1,6);
    if(result==true){
        cout<<"删除元素值在"<<"1~6的元素后的"<<"数组:";
        print(arr);
    }
    else cout<<"输入有误"<<endl;

    cout<<"****************************************"<<endl;

    //两个有序数组的初始化
    Arr arr1;Arr arr2;
    arr1.data=new int[5]{1,2,5,7,9};
    arr1.lenth=5;
    arr2.data=new int[4]{2,4,10,11};
    arr2.lenth=4;

    //合并两个有序数组
    Arr arr3;arr3.data=new int[9];arr3.lenth=9;
    CombineArrs(arr1,arr2,arr3);
    cout<<"合并两个有序数组后的数组是:";
    print(arr3);

    //逆置子数组
    ExChangeSubArr(arr3,5,4);
    cout<<"调换子数组位置后:";
    print(arr3);

    //二分查找
    Arr arr4;arr4.data=new int[8]{1,2,3,4,5,6,7,8};arr4.lenth=8;
    cout<<"元素值为"<<3<<"的元素位置在"<<Dichotomous(arr4,3)+1<<endl;

    //查找两个等长升序数组的中位数
    Arr arr5;arr5.data=new int[5]{11,13,15,16,17};arr5.lenth=5;
    Arr arr6;arr6.data=new int[5]{1,2,3,7,20};arr6.lenth=5;
    cout<<"中位数为:"<<SearchMiddle2(arr5,arr6)<<endl;

    //找出主元素
    Arr arr7;arr7.data=new int[8]{1,2,5,3,5,5,5,5},arr7.lenth=8;
    cout<<"该数组中存在主元素:"<<SearchMainElement(arr7)<<endl;

    //找出未出现的最小正整数
    print(arr7);
    cout<<"其中未出现的最小正整数为:"<<getSmallestAbsentNum(arr7)<<endl;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值