王道2025数据结构课后题大题代码---顺序表

2.2课后题

个人学习所记录笔记,便于复习查看,如有错误,请见谅。

代码均为自己的思路,与标准答案有差异

前半部分为基本的添删改查方法,便于课后题的调用

后半部分为课后题代码

#include <iostream>
#include <map>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

const int  MaxSize =50;
//静态分配
struct SeqList {
    int data[MaxSize];
    int length;
};
//初始化
void InitList(SeqList& L) {
    for (int i = 0; i <MaxSize; i++) {
        L.data[i] = 0;
    }
    L.length = 0; 
}
//插入操作
bool ListInsert(SeqList& L, int i, int e) {
    //如果插入位置不对
    if (i<1 || i>L.length + 1)
        return false;
    //如果数组已满
    if (L.length > MaxSize)
        return false;
    //正常操作
    //先对i后面的数后移
    for (int j = L.length; j >= i; j--) {
        L.data[j] = L.data[j - 1];
    }
    //i是位置,i-1是下标
    L.data[i-1] = e;
    L.length++;
    return true;
}
//删除操作
bool ListDelete(SeqList& L, int i, int &e) {
    //首先判断是否合法
    if (i<1 || i>L.length)
        return false;
    //得到删除的元素
    e =L.data[i - 1] ;
    for (int j = i; j < L.length; j++) {
        L.data[j - 1] = L.data[j];
    }
    L.length--;
    return true;
}

//按位查找
void ListGetELem(SeqList L, int i) {
    cout<< L.data[i - 1]<<endl;
}

//按值查找
void ListLocateElem(SeqList L, int x) {
    bool found = false;
    for (int i = 0; i < L.length; i++) {
        if (L.data[i] == x) {
            cout << "该元素在第" << i + 1 << "位" << endl;
            found = true;
            break;  // 找到了就退出循环
        }
    }
    if (!found) {
        cout << "没有找到元素" << endl;
    }
}


//打印顺序表的元素
void print(SeqList L) {
    cout << "此时表中数据为:" << endl;
    for (int i = 0; i < L.length; i++) {
        cout << L.data[i] << " ";
    }
    cout << endl;
}




// 课后习题
// /// 
//例题1
void test01(SeqList& L) {
    cout << "执行例题1:" << endl;
    if (L.length == 0) {
        cout << "表为空" << endl;
        return;
    }
    //分别用来记录最小值和他的位置
    int mi=L.data[0];
    int idx=0;
    for (int i = 1; i < L.length; i++) {
        if ( L.data[i]<=mi) {
            mi = L.data[i];
            idx = i;
        }
    }
    int e = mi;
    L.data[idx] = L.data[L.length - 1];  
    cout <<" 最小的值为:" << e << endl;
    print(L);
}

//例题2 逆序排列表中数据
void test02(SeqList& L) {
    for (int i = 0, j = L.length - 1; i < j; i++, j--) {
        int temp=L.data[i];
        L.data[i] = L.data[j];
        L.data[j] = temp;
    }
    print(L);
}

//例题3,删除值为x的值
void test03(SeqList& L, int x) {
    int k = 0;
    for (int i = 0; i < L.length; i++) {
        //如果查到了
        if (L.data[i] != x) {
            L.data[k] = L.data[i];
            k++;
        } 
    }
    L.length = k;
}

//例题4,删除s,t之间的所有值
void test04(SeqList& L, int s, int t) {
    int k = 0;
    if(L.length == 0){
        cout << " 顺序表为空"<<endl;
    }
    else if (s > t) {
        cout << " 定值不合理"<<endl;
    }
    else 
    {
        for (int i = 0; i < L.length; i++) {
            int a = L.data[i];
            //不在这个区间
            if (a<s || a>t) {
                L.data[k] = a;
                k++;
            }
        }
        L.length = k;
    }
}

//例题5,删除表中重复元素
void test05(SeqList& L) {
    int k = 0;
    map<int, int> mp;

    for (int i = 0; i < L.length; i++) {
        mp[L.data[i]]++;
    }

    for (auto j : mp) {
        L.data[k] = j.first;
        k++;
    }
    L.length = k;
}

//例题6 ,将两个有序顺序表合成一个
// 这个算法很典型,需要牢固掌握
void test06(SeqList& A, SeqList& B, SeqList& C) {
    
    InitList(A);
    //此时a表中数据为1 3 5 7
    ListInsert(A, 1, 1);

    ListInsert(A, 2, 3);

    ListInsert(A, 3, 5);

    ListInsert(A, 4, 7);

   
    InitList(B);
    //此时b表中数据为2 4 6
    ListInsert(B, 1, 2);

    ListInsert(B, 2, 4);

    ListInsert(B, 3, 6);

    //将其合并到c表中,结果应该为1 2 3 4 5 6 7
    InitList(C);
    int i = 0, j = 0, k = 0;
    while (i < A.length && j < B.length) {
        if (A.data[i] <= B.data[j]) {
            C.data[k++] = A.data[i++];
        }
        else {
            C.data[k++] = B.data[j++];
        }
    }

    // 将剩余元素添加到结果顺序表 C
    while (i < A.length) {
        C.data[k++] = A.data[i++];
    }
    while (j < B.length) {
        C.data[k++] = B.data[j++];
    }

    C.length = k; // 更新结果顺序表 C 的长度
    cout << "a中数据为" << endl;
    print(A);
    cout << "b中数据为" << endl;
    print(B);
    cout << "c中数据为" << endl;
    print(C);
}

//例题7,实际上就是数组部分反转
//可以利用vector数组的reverse方法
void test07() {
    // 前部分长度为3,后面为4
    vector<int> a = { 1, 2, 3, 4, 5, 6, 7 };

    // 将前部分反转
    reverse(a.begin(), a.begin() + 3);  // 3 2 1 4 5 6 7

    // 将后部分反转
    reverse(a.begin() + 3, a.end());    // 3 2 1 7 6 5 4

    // 将整个数组反转
    reverse(a.begin(), a.end());        // 4 5 6 7 1 2 3

    // 输出结果以验证
    for (int num : a) {
        cout << num << " ";
    }
    cout << endl;
}

//例题8 查找数据,找到交换相邻位置,找不到插入最后
//这段代码也能完成,但是不是最快的
void test08(SeqList& L, int x) {
    int i;
    bool flag = 0;
    //如果找到了
    for (i = 0; i < L.length; i++) {
        if (L.data[i] == x) {
            if (i < L.length - 1) {
                int temp = L.data[i];
                L.data[i] = L.data[i + 1];
                L.data[i + 1] = temp;
                flag = 1;
            }
            break;
        }
        else if (L.data[i] > x) {
            break;
        }
    }
    //如果没有找到
    if (flag == 0) {
        if (i == L.length || L.data[i] > x) {
            // 插入元素
            if (L.length >= MaxSize) {
                cout << "顺序表已满,无法插入元素" << endl;
                return;
            }
            for (int j = L.length; j > i; j--) {
                L.data[j] = L.data[j - 1];
            }
            L.data[i] = x;
            L.length++;
        }
    }
}
 
//例题9  输出三个数组中相同的元素
//另一种做法,遍历三个数组中的数据到map函数中,输出map中值为3的数据,但是该方法时间复杂度较高
void test09(int n) {
    int a[] = { 1,2,3 };
    int b[] = { 2,3,4 };
    int c[] = { 2,4,6 };

    int i=0, j=0, k=0;//指针
    //n代表着判断次数,即最短的数组的长度??
    while (i < n && j < n && k < n) {
        //如果三个数组元素相同
        if (a[i] == b[j] && b[j] == c[k]) {
            cout << a[i] << endl;
            i++;
            j++;
            k++;
        }
        //如果不相同
        //最大的数据所指向的下标不动,其他的自增
        int ma = max(max(a[i], b[i]), c[i]);
        if (a[i] < ma) i++;
        if (b[i] < ma) j++;
        if (c[i] < ma) k++;

    }
}

//例题10 循环左移
//时间和空间复杂度均为on,也可采用例题7的方法,空间复杂度变为o1
void test10() {
    vector<int> a = { 1, 2, 3, 4, 5 };
    cout << "输入左移次数" << endl;
    int p; cin >> p;

    // 求出数组a的长度
    int len = a.size();

    // 元素移动次数
    int pp = p % len;

    vector<int> b(len);
    for (int i = 0; i < len; i++) {
        // 计算新位置,并确保索引为正数
        int newPos = (i + len - pp) % len;
        b[newPos] = a[i];
    }

    for (int i = 0; i < len; i++) {
        cout << b[i] << " ";
    }
    cout << endl; // 别忘了在输出完后换行
}

//例题11 求两个数列的中位数
//思路:可以把两个数列合成一个,然后求中位数
//也可以用指针依次遍历判断,类似例题9,
void test11() {
    //采用思路2
    vector<int> a = { 11, 13, 15, 17, 19 };
    vector<int> b = { 2, 4, 6, 8, 20, 21 };

    double len1 = a.size();
    double len2 = b.size();
    //向上取整
    int len = ceil((len1 + len2) / 2.0); // 确保使用浮点数计算

    int i = 0, j = 0, k = 0;
    int mi = 0;

    while (k < len) {
        //防止越界或者一个数组遍历完成
        if (i < a.size() && (j >= b.size() || a[i] < b[j])) {
            mi = a[i];
            i++;
        }
        else {
            mi = b[j];
            j++;
        }
        k++;
    }

    cout << mi << endl;
}

//例题12 求主元素(数组中数据最多的元素且数量大于一半)
void test12() {
    vector<int> a = { 0,5,5,3,5,7,5,5 };
    map<int, int> mp;

    for (int i = 0; i < a.size(); i++) {
        mp[a[i]]++;
    }
    int n = a.size();

    int ma = 0;
    int maxnum = -1;
    for (auto j : mp) {
        if (j.second > ma) {
            ma = j.second;
            maxnum = j.first;
        }
    }
   
    if (ma > n / 2) {
        //输出ma所对应的那个元素
        for (auto j : mp) {
            if (j.second == ma)
                cout << j.first;
        }
    }
    else {
        cout << -1;
    }
}

//例题13 找出数组中未出现的最小正整数
void test13() {
    vector<int> a = { -5,0,2,3 };

    bool vis[100] = { 0 };
    for (int i = 0; i < a.size(); i++) {
        if (a[i] >= 0) {
            vis[a[i]] = 1;
        }
    }
    for (int i = 0; i < a.size(); i++) {
        int temp = i;
        if (vis[i] == 0) {
            cout << temp << endl;
            break;
        }
    }
}

//例题14
void test14() {
    vector<int> arr1 = { -1, 0, 9 };
    vector<int> arr2 = { -25, -10, 10, 11 };
    vector<int> arr3 = { 2, 9, 17, 30, 41 };

    sort(arr1.begin(), arr1.end());
    sort(arr2.begin(), arr2.end());
    sort(arr3.begin(), arr3.end());

    int i = 0, j = 0, k = 0;
    //最小的值
    int min_dist = INT_MAX;
    //通过指针对三个数组数据进行遍历
    while (i < arr1.size() && j < arr2.size() && k < arr3.size()) {
        int dist = abs(arr1[i] - arr2[j]) + abs(arr2[j] - arr3[k]) + abs(arr3[k] - arr1[i]);

        if (dist < min_dist) {
            min_dist = dist;
        }

        //将指针(或索引)移动到三个数组中最小元素的位置
        if (arr1[i] <= arr2[j] && arr1[i] <= arr3[k]) {
            i++;
        }
        else if (arr2[j] <= arr1[i] && arr2[j] <= arr3[k]) {
            j++;
        }
        else {
            k++;
        }
    }

    cout << "最短距离为:" << min_dist << endl;
}
int main() {
    SeqList A;
    SeqList B;
    SeqList C;
    SeqList L;
    InitList(L);

    ListInsert(L, 1, 1);

    ListInsert(L, 2, 2);

    ListInsert(L, 3, 3);

    ListInsert(L, 4, 4);

    ListInsert(L, 5, 5);
    print(L);
    cout << "------" << endl;


    //test06(A, B, C);
    //test08(L,6);
    //test04(L,1,3);
    //print(L);
    
    test14();
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值