顺序表课后题
废话不多说,直接上代码,记录一下
#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;
}