线性表的代码习题

文章介绍了如何在顺序表中高效地删除所有值等于特定元素、根据基准元素分区以及将奇数移动到偶数前面的算法,包括整体建表法、元素移动法、快速排序思想和元素交换策略。
摘要由CSDN通过智能技术生成

顺序表的应用:

顺序表的结构体:

#define ElemType int 
#define Maxsize 50
typedef struct {
    ElemType data[Maxsize];
    int length;
}Sqlist;

一.题目1:

        假设一个线性表采用顺序表表示,设计一个算法,删除其中所有值等于x的元素,要求算法的时间复杂度O(n),空间复杂度为O(1)。

方法1:整体建表法

        思路:使用 i 遍历 L。使用 k 记录 L 中元素值等于e的个数。当 i 指向元素值等于 e 时 k+1;但是不移动元素位置,之后i移动到后面不等于e 的元素,则需要前移,L->data[i-k]=L->data[i].最后长度减少 k。 

void delNode(Sqlist*& L, ElemType e) {
    int k = 0;
    for (int i = 0; i < L->length; i++) {
        if (L->data[i] != e) {
            L->data[k] = L->data[i];
            k++;
        }
    }
    L->length = k;

方法2:元素移动法

        思路:使用 i 遍历 L。使用 k 记录 L 中元素值等于e的个数。当 i 指向元素值等于 e 时 k+1;但是不移动元素位置,之后i移动到后面不等于e 的元素,则需要前移,L->data[i-k]=L->data[i].最后长度减少 k。 

void delNode2(Sqlist*& L, ElemType e) {
    int k = 0;
    for (int i = 0; i < L->length; i++) {
        if (L->data[i] != e) {
            L->data[i - k] = L->data[i];
        }
        else {
            k++;
        }
    }
    L->length -= k;
}

二.题目2:

        有一个顺序表 L,假设元素类型ElemType 为整型,设计一个尽可能高效的算法,以第一个元素为基准,将所有小于或等于它的元素移动到该基准的前面,将所有大于它的元素移动到该基准的后面。(类似于后面排序中的快速排序的思想,少了一个递归)

方法1:快速排序的思想

        思路:将第一个元素存储在 变量 base 中,使用 i 从前面遍历,使用 j 从后面遍历, 当 j 遍历发现一个当前值比 base 大的话,j--;反之比base小,那么 j 不变,将当前 j 的元素放置于 i 的空白位置上,之后从 i 开始,当 i 遍历发现当前值比 base 小时,i++;反之;i不变,将当前 i 的元素放置在 j 的空白位置上,直到i=j,那么就是 base基准元素的位置。

void partition(Sqlist*& L) {
    int i = 0; 
    int j = L->length - 1;
    ElemType base = L->data[0];

    while (i < j) {
        while (i<j && L->data[j]>base)
            j--;
        L->data[i] = L->data[j];
        while (i < j && L->data[i] < base)
            i++;
        L->data[j] = L->data[i];
    }
    L->data[i] = base;
}

方法2:元素交换法

        思路: 将 L->data[0] 放于 base 上,之后 i 从左往右开始查找, j 从右往左开始查找。 i != j 的时候循环,i 从左往右找一个大于  base的元素,j 从右往左找一个小于 base 的元素,之后将两个交换位置,data[i] 和 data[j] 进行交换。

void swap(ElemType &a, ElemType &b) {
    int num;
    num = a;
    a = b;
    b = num;
}



void partition2(Sqlist*& L,ElemType e) {
    int i = 0;
    int j = L->length - 1;
    ElemType base = e;
    while (i < j) {
        while (i<j && L->data[i]<base) 
            i++;
        while (i<j && L->data[j]>base)
            j--;
        if (i < j)
            swap(L->data[i], L->data[j]);
    
    }
    swap(L->data[0], L->data[i]);               // 这里不能使用 L->data[i]=0;因为中间元素并没有被寄放
}

三.题目3:

        有一个顺序表 L;假设元素类型 ElemType 为整型,设计一个尽可能高效的算法将所有奇数移动到偶数的前面。

方法1:元素交换法;类似于 Example 2的方法,只不过改变了判定条件

void movel(Sqlist*& L) {
    int i = 0;
    int j = L->length - 1;
    while (i < j) {
        while (i < j && L->data[i] % 2 != 0)
            i++;
        while (i < j && L->data[j] % 2 == 0)
            j--;
        if (i < j)
            swap(L->data[i], L->data[j]);
    }
}

方法2:区间划分法

        思路:将顺序表的前半段作为奇数区间。L->data[0……i] 表示的是奇数区间。i表示的是奇数区间的最后一个元素。起初将 i置为-1,表示奇数区间是空的。然后使用 j从左往右遍历所有的元素,若出现一个奇数,那么 i+1,并且将 L->data[i] 与 L->data[j] 进行交换位置。j继续遍历。

void move2(Sqlist*& L){
    int i = -1;
    for (int j = 0; j < L->length - 1; j++) {
        if (L->data[j] % 2 != 0) {
            i++;        
            if (i != j)
                swap(L->data[i], L->data[j]);
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值