王道——顺序表编程题

1.从顺序表中删除具有最小值的元素(假设唯一)并有函数返回被删元素的值。空出的位置由最后一个元素填补,若顺序表为空则显示出错信息并退出运行。

struct ll
{
    int nums[10]= {1,3,4,9,7,5,2,6,8,0};
    int length=10;
    int max_size=10;

    int del_min()
    {
        if(length==0)
        {
            cout<<"顺序表为空"<<endl;
            return -1;
        }
        int m = nums[0];
        int p = 0;
        for(int i=1; i<length; i++)
        {
            if(m>nums[i])
            {
                m=nums[i];
                p=i;
            }
        }
        nums[p]=nums[length-1];
        length--;
        return m;
    }
} l;

3.对长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表所有值为x的数据元素

    int del_x(int n)
    {
        int k=0;
        for(int i=0;i<length;i++)
        {
            if(nums[i]!=n)
            {
               nums[k]=nums[i];
               k++;
            }
        }
        length=k;
        show();

    }

4(5).从(有序)顺序表中删除其值在给定值s与t之间(要求s<t)的所有元素,如果s或t不合理或顺序表为空,则显示出错信息并退出运行。

    void del_s_t(int s,int t)
    {
        if(s>=t||length==0)
            cout<<"error"<<endl;
        else{
            int k=0;
            for(int i=0;i<length;i++)
            {
                if(nums[i]<s||nums[i]>t)
                {
                    nums[k]=nums[i];
                    k++;
                }
            }
            length=k;
            show();
        }
    }

6.从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均为不同

    void del_repeat()
    {
        if(length==0)
        {
            cout<<"顺序表为空"<<endl;
            return;
        }
        int k=1;
        int n=nums[0];
        for(int i=1;i<length;i++)
        {
            if(nums[i]!=n)
            {
                n=nums[i];
                nums[k]=n;
                k++;
            }
        }
        length=k;
        show();
    }

7.将两个有序顺序表合并为一个新的有序顺序表,并由函数返回的结果顺序表

    ll union_l(ll l)
    {
        int temp[100];
        int k=0;
        int l1=0;
        int l2=0;
        while(l1<length&&l2<l.length)
        {
            if(nums[l1]<l.nums[l2])
            {
                temp[k]=nums[l1];
                k++;
                l1++;
            }
            else
            {
                temp[k]=l.nums[l2];
                k++;
                l2++;
            }
        }
        if(l1<length)
        {
            for(int q=l1; q<length; q++)
            {
                temp[k]=nums[q];
                k++;
            }
        }
        if(l2<l.length)
        {
            for(int q=l2; q<l.length; q++)
            {
                temp[k]=l.nums[q];
                k++;
            }
        }
        maxsize=max(length,maxsize);
        for(int i=0;i<k;i++)
        {
            nums[i]=temp[i];
        }
        length=k;
        show();
        return l;
    }

8.已知在一维数组A[m+n]中依次存放两个线性表(a1,a2,a3,...,am)和(b1,b2,b3,...,bn)。试编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,b3,...,bn)放在(a1,a2,a3,...,am)的前面

思路:现将整个数组倒置,再将前面长度为n的元素单独倒置,再讲后面长度为m的元素单独倒置。

灵活使用倒置很重要

typedef int DataType;
void Reverse(DataType A[],int left,int right, int arraySize){
    if(left>=right||right||>=arraySize)
        return;
    int mid(left+right)/2
    for(int i=0;i<=mid-left;i++)
    {
        Datatype temp = A[left+i];
        A[left+i] = A[right-i];
        A[right-i] = temp;
    }
}
void Exchange(DataType A[],int m,int n,int arraySize){
    Reverse(A,0,m+n-1,arraySize);
    Reverse(A,0,n-1,arraySize);
    Reverse(A,n,m+n-1,arraySize);
}

9.线性表(a1,a2,a3,...,an)中的元素递增有序且按顺序存储与计算机内。要求设计一算法,完成用最少时间在表中查找数值为x的元素,若找到则将其与后继元素位置想交换

    void insert_x(int x)
    {
        int l=0;
        int r=length-1;
        int mid;
        while(l<=r)
        {
            mid = (l+r)/2;
            if(nums[mid]==x)
            {
                int temp = nums[mid];
                nums[mid]=nums[mid+1];
                nums[mid+1]=temp;
                show();
                return;
            }
            if(nums[mid]>x)
            {
                r=mid-1;
            }else{
                l=mid+1;
            }
        }
        if(length==maxsize){
            cout<<"error"<<endl;
            return;
        }
        for(int i=length;i>l;i--)
        {
            nums[i]=nums[i-1];
        }
        nums[l]=x;
        length++;
        show();
        return;

    }

10.设将n(n>1)个整数存放在一维数组R中。设计一个时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0<p<n)个位置,即将R中的数据由(X0,X1,...,Xn-1)变换为(Xp,Xp+1,...,Xn-1,X0,X1,...,Xp-1)。要求

1)给出算法的基本设计思想

先将所有数倒置,然后从尾部起往前的p个数单独倒置,剩余的数单独倒置

时间复杂度O(n),空间复杂度O(1)

#include <iostream>

using namespace std;

int n[10]={0,1,2,3,4,5,6,7,8,9};

void reverse_array(int n[10],int b,int p)
{
    int mid = (b+p)/2;
    for(int i=b;i<mid;i++)
    {
        int temp;
        temp=n[i];
        n[i]=n[p-i+b];
        n[p-i+b]=temp;
    }
}

int main()
{
    int p;
    cin>>p;
    reverse_array(n,0,9);
    reverse_array(n,0,p-1);
    reverse_array(n,p,9);
    for(int i=0;i<10;i++)
        cout<<n[i]<<' ';
    return 0;
}

11.一个长度为L(L>=1)的升序序列S,处在第[L/2]个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=中位数是15,两个序列的中位数是含它们所有元素的升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两序列的A和B的中位数

设计思想:

分别求两个升序序列A、B的中位数,设为a和b,求序列A,B的中位数过程如下

  1. 若a=b,则a或b即为所求中位数,算法结束。
  2. 若a<b,则舍弃序列A中较小的一半,同时舍弃序列B中较大的一半,要求两次舍弃的长度相等
  3. 若a>b,则舍弃序列A中较大的一半,同时舍弃序列B中较小的一半,要求两次舍弃的长度相等

时间复杂度为O(logn),空间复杂度为O(1)

void M_Search(int A[],int B[],int n)
{
    int s1=0,d1=n-1,m1,s2=0,d2=n-1,m2;
    //分别表示序列A和B的首位数
    while(s1!=d1||s2!=d2)
    {
        m1=(s1+d1)/2;
        m2=(s2+d2)/2;
        if(A[m1]==B[m2])
            return A[m1];
        if(A[m1]<B[m2])
        {
            if((s1+d1)%2==0)
            {
                s1=m1;
                d2=m2;
            }
            else
            {
                s1=m1+1;
                d2=m2;
            }
        }else{
            if((s2+d2)%2==0)
            {
                d1=m1;
                s2=m2;
            }else{
                d1=m1;
                s2=m2+1;
            }
        }
        return A[s1]<B[s2]?A[s1]:B[s2];
    }
}

12.已知一个整数序列A=(a0,a1,...,an),其中0<=ai<n(0<=i<n)。存在ap1=ap2=...=apm=x且m>n/2(0<=pk<n,1<=k<=m),则称x为A的主元素。找出主元素

时间复杂度为O(n),空间复杂度为O(1)

int Majority(int A[],int n){
    int i,c,count=1;
    c=A[0];
    for(i=1; i<n; i++)
    {
        if(A[i]==c)
        {
            count++;
        }
        else
        {
            if(count>0)
                count--;
            else
            {
                c=A[i];
                count=1;
            }
        }
    }
    count=0;
    for(int i=0; i<n; i++)
    {
        if(c==A[i])
            count++;
    }
    if(count>n/2) return c;
    else return -1;
}

13.给定一个含n(n>=1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小整数。

算法的时间复杂度O(n),空间复杂度O(1)

int findmin(int A[],int n)
{
    int i,*B;
    B=(int *)malloc(sizeof(int) *n);
    memset(B,0,sizeof(B));
    for(int i-0;i<n;i++)
    {
        if(A[i]>0&&A[i]<n)
            B[A[i]-1]=1;
    }
    for(i=0;i<n;i++)
        if(B[i]==0)
            break;
    return i+1;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值