(王道)数据结构顺序表基础代码题C

以下应用题全部来自2021版王道应用题

设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)

算法思想:一开始我都没仔细读题 还纳闷时间复杂度为O(1) 这怎么想呢 跟链表一样吗 设计一个头指针与尾指针 他俩调换就行了?后来一看题才是空间复杂度 这才是我们所熟悉的题
L->data[L->last-i] = L->data[i] 从前往后一直循环到 last/2 跳出 具体代码如下:

int myreverse(sequenlist *L){
    for (int i=0; i<=L->last/2; i++) {
        datatype temp = L->data[L->last-i];
        L->data[L->last-i] = L->data[i];
        L->data[i] = temp;
    }
    return 1;
}



线

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

如果我们还用上节课所学的知识来写代码话 我们会先遍历找到第一个x然后实现删除操作 全部都向前平移 平移完再找到第二个然后再平移 显然 时间复杂度为O(n2) 那么怎么实现O(n)呢 这里我们就需要引入一个变量 k 来记录第i个元素前 有多少个重复的元素 注意是变量k 对于不同的元素 k的值是不同的 让我们来看具体代码:

int FindAllXtodelete(sequenlist *L,datatype x){
    int k=0;  //作为x的个数 
    for (int i=0; i<=L->last; i++) {
        if (L->data[i] == x) {
            k++;
        }
        else
            L->data[i-k] = L->data[i];   //向前移动k个单位
    }   
    L->last = L->last-k
    return 1;
}



线

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

算法思想 其实本题与上一题思想相同 就是if条件发生了改变 让我们具体看一下代码

int Delete_s_t(sequenlist *L,datatype s,datatype t){
    if (s>=t||L->last+1<=0) {
        printf("error");
        return 0;
    }
    int i;
    int k=0;
    for ( i=0; i<=L->last; i++) {
        if(L->data[i]>=s&&L->data[i]<=t)
            k++;
        else
            L->data[i-k] =  L->data[i];
    }
    L->last = i;
    return 1;
}



线

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

思想:让我们回顾直接插入排序 让我们复制一个顺序表取第j个元素与顺序表最后一个元素相比 若相同j++ 若不同就可以在i后面插入元素了 需要我们思考的是i后面那个元素位置怎么表示呢 最后 i也就是我们L->last的值 L->last指向下标呦
让我们来看下代码:

int DeleteOrderlySequence(sequenlist *L){
    if (L->last+1<=0) {
        printf("error");
        return 0;
    }
    int i,j;     //i存储第一个不相同的元素   j为工作指针
    for (i=0,j=1; j<=L->last; j++) {
        if (L->data[i]!=L->data[j]) {
            i++;
            L->data[i] = L->data[j];
            //以上两行代码也能简写成 L->data[++i] = L->data[j];
            //注意 ++i 与i++ 他们俩是有区别 下个题你就能看到i++ 了
        }
    }
      L->last = i;
    return 1;
}



线

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

思想:首先就是在创建一个顺序表 表长等于那两个表加起来 三个表相对应的那肯定有三个变量 i,j,k来表示他们的下标 判断条件 两个表里的元素谁小 就把谁放在新表里 新表下标加1 小的那个表下标也加1 总有一个表先放完 一个表后放完 一个表放完后 跳出循环 直接把第二个表剩下的元素放进新表就OK了 代码如下:

int MergerOrderlySequence(sequnelist *L,sequnelist *L1,sequnelist *L2){
    int i,j,k;
    if (L1->last+L12->last+1>L->last) {
        printf("error");
        return 0;
    }
    
    while ((L1->last+1)--&&(L2->last+1)--) {
        if (L1->data[i]<=L2->data[j]) {
            L->data[k++] =  L1->data[i++];  //先赋值再自增 ☆
        }
        else
            L->data[k++] =  L2->data[j++];
    }
    while (i<=L1->last) {
         L->data[k++] =  L1->data[i++];
    }
    while (j<=L2->last) {
         L->data[k++] =  L1->data[j++];
    }
        
    L->last=k-1;  // 程序结束前 k还是会执行自增操作 所以k代表着顺序表的长度 k-1才是下标
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值