分类: C++

  • #C++ Day45 Basic Data Structure Chapter3  review-2  January 2 2026

    4.猜数字

    LCP 01. 猜数字

    已解答

    简单

    小A 和 小B 在玩猜数字。小B 每次从 1, 2, 3 中随机选择一个,小A 每次也从 1, 2, 3 中选择一个猜。他们一共进行三次这个游戏,请返回 小A 猜对了几次?

    输入的guess数组为 小A 每次的猜测,answer数组为 小B 每次的选择。guess和answer的长度都等于3。

    示例 1:

    输入:guess = [1,2,3], answer = [1,2,3]

    输出:3

    解释:小A 每次都猜对了。

    示例 2:

    输入:guess = [2,2,3], answer = [3,2,1]

    输出:1

    解释:小A 只猜对了第二次。

    限制:

    1. guess的长度 = 3
    2. answer的长度 = 3
    3. guess的元素取值为 {1, 2, 3} 之一。
    4. answer的元素取值为 {1, 2, 3} 之一。

    myanswer:

    class Solution {

    public:

        int game(vector<int>& guess, vector<int>& answer) {

            int count=0;

            for(int i=0;i<3;i++){

                if(guess[i] == answer[i]){

                    count++;

                }

            }

            return count;

        }

    };

    5.拿硬币 

    LCP 06. 拿硬币

    已解答

    简单

    相关标签

    桌上有 n 堆力扣币,每堆的数量保存在数组 coins 中。我们每次可以选择任意一堆,拿走其中的一枚或者两枚,求拿完所有力扣币的最少次数。

    示例 1:

    输入:[4,2,1]

    输出:4

    解释:第一堆力扣币最少需要拿 2 次,第二堆最少需要拿 1 次,第三堆最少需要拿 1 次,总共 4 次即可拿完。

    示例 2:

    输入:[2,3,10]

    输出:8

    限制:

    • 1 <= n <= 4
    • 1 <= coins[i] <= 10

    class Solution {

    public:

        int minCount(vector<int>& coins) {

            int ret = 0;

            for(int i=0;i<coins.size();i++){

               ret += (coins[i] + 1) /2; 

               //如果偶数这个+1 无效 奇数把最后一次当1

            }

        return ret;

        }

    };

    2.数值统计

    数值统计 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 224358    Accepted Submission(s): 104159

    Problem Description 统计给定的n个数中,负数、零和正数的个数。  
    Input 输入数据有多组,每组占一行,每行的第一个数是整数n(n<100),表示需要统计的数值的个数,然后是n个实数;如果n=0,则表示输入结束,该行不做处理。  
    Output 对于每组输入数据,输出一行a,b和c,分别表示给定的数据中负数、零和正数的个数。  
    Sample Input 6 0 1 2 3 -1 0 5 1 2 3 4 0.5 0   
    Sample Output 1 2 3 0 0 5  
    Author lcy  
    Source C语言程序设计练习(二)

    //Sequential List – value statistics

    #include <iostream>

    using namespace std;

    #define eleType double

    //1.define a structure

    struct SequentialList {

    eleType* elements;

    int capacity;

    int size;

    };

    //2.initialize

    void initializeList(SequentialList* list, int capacity) {

    list->elements = new eleType[capacity];

    list->capacity = capacity;

    list->size = 0;

    }

    //3.destroy

    void destroyList(SequentialList* list) {

    delete[] list->elements;

    list->elements = nullptr;

    list->size = 0;

    list->capacity = 0;

    }

    //4.size and is it empty

    int sizeOfList(SequentialList* list) {

    return list->size;

    }

    bool isEmpty(SequentialList* list) {

    return list->size == 0;

    }

    //5.insert

    void insertElement(SequentialList* list, int index, eleType element) {

    if (index<0 || index>list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->capacity == list->size) {

    int newcapacity = (list->capacity == 0) ? 4 : list->capacity * 2;

    eleType* newlist = new eleType[newcapacity];

    for (int i = 0; i < list->size; i++) {

    newlist[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = newlist;

    list->capacity = newcapacity;

    }

    for (int i = list->size; i > index; i–) {

    list->elements[i] = list->elements[i – 1];

    }

    list->elements[index] = element;

    list->size++;

    }

    //6.delete

    void deleteElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    for (int i = index; i < list->size – 1; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    //7.findindex

    int findIndex(SequentialList* list, eleType element) {

    for (int i = 0; i < list->size; i++) {

    if (list->elements[i] == element) {

    return i;

    }

    }

    return -1;

    }

    //8.get

    eleType getElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    //9.update

    void updateElement(SequentialList* list, int index, eleType element) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = element;

    }

    int main() {

    SequentialList mylist;

    int n;

    while (cin >> n && n!=0 ) {

    initializeList(&mylist, n);

    for (int i = 0; i < n; i++) {

    double val;

    cin >> val;

    insertElement(&mylist, i, val);

    }

    double a=0, b=0, c=0;

    for (int i = 0; i < n; i++) {

    if (getElement(&mylist, i) > 0) {

    c++;

    }

    else if(getElement(&mylist, i) < 0){

    a++;

    }

    else {

    b++;

    }

    }

    cout << a <<‘ ‘ << b << ‘ ‘ << c <<endl ;

    destroyList(&mylist);

    }

    return 0;

    }

    //Sequential List – value statistics

    #include <iostream>

    using namespace std;

    #define eleType double

    //1.define a structure

    struct SequentialList {

    eleType* elements;

    int capacity;

    int size;

    };

    //2.initialize

    void initializeList(SequentialList* list, int capacity) {

    list->elements = new eleType[capacity];

    list->capacity = capacity;

    list->size = 0;

    }

    //3.destroy

    void destroyList(SequentialList* list) {

    delete[] list->elements;

    list->elements = nullptr;

    list->size = 0;

    list->capacity = 0;

    }

    //4.size and is it empty

    int sizeOfList(SequentialList* list) {

    return list->size;

    }

    bool isEmpty(SequentialList* list) {

    return list->size == 0;

    }

    //5.insert

    void insertElement(SequentialList* list, int index, eleType element) {

    if (index<0 || index>list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->capacity == list->size) {

    int newcapacity = (list->capacity == 0) ? 4 : list->capacity * 2;

    eleType* newlist = new eleType[newcapacity];

    for (int i = 0; i < list->size; i++) {

    newlist[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = newlist;

    list->capacity = newcapacity;

    }

    for (int i = list->size; i > index; i–) {

    list->elements[i] = list->elements[i – 1];

    }

    list->elements[index] = element;

    list->size++;

    }

    //6.delete

    void deleteElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    for (int i = index; i < list->size – 1; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    //7.findindex

    int findIndex(SequentialList* list, eleType element) {

    for (int i = 0; i < list->size; i++) {

    if (list->elements[i] == element) {

    return i;

    }

    }

    return -1;

    }

    //8.get

    eleType getElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    //9.update

    void updateElement(SequentialList* list, int index, eleType element) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = element;

    }

    int main() {

    SequentialList mylist;

    int n;

    while (cin >> n && n!=0 ) {

    initializeList(&mylist, n);

    double neg = 0, zero = 0, pos = 0;

    for (int i = 0; i < n; i++) {

    double val;

    cin >> val;

    if (val > 0) {

    pos++;

    }

    else if (val < 0) {

    neg++;

    }

    else {

    zero++;

    }

    }

    cout << neg <<‘ ‘ << zero << ‘ ‘ << pos <<endl ;

    destroyList(&mylist);

    }

    /*return 0;

    Run ID Submit Time Judge Status Pro.ID Exe.Time Exe.Memory Code Len.Language Author

    40643282 2026 – 01 – 02 07:37 : 49 Accepted 2008 15MS 1812K 2546 B C++ supervito

    40643281 2026 – 01 – 02 07 : 37 : 19 Accepted 2008 15MS 1812K 2549 B C++ supervito

    40643280 2026 – 01 – 02 07 : 17 : 40 Accepted 2008 0MS 1812K 2626 B C++ supervito*/

    }

    4.青年歌手大奖赛_评委会打分

    青年歌手大奖赛_评委会打分 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 184150    Accepted Submission(s): 90169

    Problem Description 青年歌手大奖赛中,评委会给参赛选手打分。选手得分规则为去掉一个最高分和一个最低分,然后计算平均得分,请编程输出某选手的得分。  
    Input 输入数据有多组,每组占一行,每行的第一个数是n(2<n<=100),表示评委的人数,然后是n个评委的打分。  
    Output 对于每组输入数据,输出选手的得分,结果保留2位小数,每组输出占一行。  
    Sample Input 3 99 98 97 4 100 99 98 97  
    Sample Output 98.00 98.50  
    Author lcy  
    Source C语言程序设计练习(三)

    #include <iostream>

    using namespace std;

    #define eleType double

    //1.define a structure

    struct SequentialList {

    eleType* elements;

    int capacity;

    int size;

    };

    //2.initialize

    void initializeList(SequentialList* list, int capacity) {

    list->elements = new eleType[capacity];

    list->capacity = capacity;

    list->size = 0;

    }

    //3.destroy

    void destroyList(SequentialList* list) {

    delete[] list->elements;

    list->elements = nullptr;

    list->size = 0;

    list->capacity = 0;

    }

    //4.size and is it empty

    int sizeOfList(SequentialList* list) {

    return list->size;

    }

    bool isEmpty(SequentialList* list) {

    return list->size == 0;

    }

    //5.insert

    void insertElement(SequentialList* list, int index, eleType element) {

    if (index<0 || index>list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->capacity == list->size) {

    int newcapacity = (list->capacity == 0) ? 4 : list->capacity * 2;

    eleType* newlist = new eleType[newcapacity];

    for (int i = 0; i < list->size; i++) {

    newlist[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = newlist;

    list->capacity = newcapacity;

    }

    for (int i = list->size; i > index; i–) {

    list->elements[i] = list->elements[i – 1];

    }

    list->elements[index] = element;

    list->size++;

    }

    //6.delete

    void deleteElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    for (int i = index; i < list->size – 1; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    //7.findindex

    int findIndex(SequentialList* list, eleType element) {

    for (int i = 0; i < list->size; i++) {

    if (list->elements[i] == element) {

    return i;

    }

    }

    return -1;

    }

    //8.get

    eleType getElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    //9.update

    void updateElement(SequentialList* list, int index, eleType element) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = element;

    }

    int main() {

    int n;

    while (cin >> n && n>2 && n<=100) {

    SequentialList mylist;

    initializeList(&mylist, n);

    for (int i = 0; i < n; i++) {

    eleType ele;

    cin >> ele;

    insertElement(&mylist, i, ele);

    }

    //eleType Emax = -10000000000, Emin = 10000000000,Esum=0; //可能会有一个非常大的数字

    eleType Emax = getElement(&mylist, 0);//假设第一个最大和最小

    eleType Emin = getElement(&mylist, 0);

    eleType Esum = 0;

    for (int i = 0; i < n; i++) {

    eleType ele = getElement(&mylist,i);

    if (Emax < ele) Emax = ele;

    if (Emin > ele) Emin = ele;

    Esum += ele;

    }

    Esum -= Emax;

    Esum -= Emin;

    Esum /= (n – 2);

    printf(“%.2lf\n”,Esum);

    destroyList(&mylist);

    }

    }

    6.值相等的最小索引

    给你一个下标从 0 开始的整数数组 nums ,返回 nums 中满足i mod 10 == nums[i]的最小下标 i ;如果不存在这样的下标,返回-1。

    x mod y 表示 x 除以 y 的 余数

    示例 1:

    输入:nums = [0,1,2]

    输出:0

    解释:

    i=0: 0 mod 10 = 0 == nums[0].

    i=1: 1 mod 10 = 1 == nums[1].

    i=2: 2 mod 10 = 2 == nums[2].

    所有下标都满足 i mod 10 == nums[i] ,所以返回最小下标 0

    示例 2:

    输入:nums = [4,3,2,1]

    输出:2

    解释:

    i=0: 0 mod 10 = 0 != nums[0].

    i=1: 1 mod 10 = 1 != nums[1].

    i=2: 2 mod 10 = 2 == nums[2].

    i=3: 3 mod 10 = 3 != nums[3].

    2 唯一一个满足 i mod 10 == nums[i] 的下标

    示例 3:

    输入:nums = [1,2,3,4,5,6,7,8,9,0]

    输出:-1

    解释:不存在满足 i mod 10 == nums[i] 的下标

    示例 4:

    输入:nums = [2,1,3,5,2]

    输出:1

    解释:1 是唯一一个满足 i mod 10 == nums[i] 的下标

    提示:

    • 1 <= nums.length <= 100
    • 0 <= nums[i] <= 9

    class Solution {

    public:

        int smallestEqual(vector<int>& nums) {

            for(int i=0;i<nums.size();i++){

                if(i % 10 == nums[i]){

                    return i;

                }

            }

            return -1;

        }

    };

    7.最大连续1的个数

    485. 最大连续 1 的个数

    已解答

    简单

    相关标签

    相关企业

    提示

    给定一个二进制数组 nums , 计算其中最大连续 1 的个数。

    示例 1:

    输入:nums = [1,1,0,1,1,1]

    输出:3

    解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.

    示例 2:

    输入:nums = [1,0,1,1,0,1]

    输出:2

    提示:

    • 1 <= nums.length <= 105
    • nums[i] 不是 0 就是 1.

    class Solution {

    public:

        int findMaxConsecutiveOnes(vector<int>& nums) {

            int max=0,temp=0;

            for(int i=0;i<nums.size();i++){

                if(nums[i]==1){

                    temp++;

                }

                else{

                    if(temp > max){                 

                        max=temp; 

                    }

                    temp = 0;

                }

            }

             if(temp > max){                 

                        max=temp; 

                    }

                    temp = 0;

            return max;

        }

    };

    class Solution {

    public:

        int findMaxConsecutiveOnes(vector<int>& nums) {

            int max_val=0,temp=0;

            for(int i=0;i<nums.size();i++){

                if(nums[i] == 1){

                    temp++;

                    if(temp>max_val){

                        max_val = temp;

                    }

                }

                else{

                    temp = 0;

                }

            }

            return max_val;

        }

    };

    //修改变量名版本

    class Solution {

    public:

        int findMaxConsecutiveOnes(vector<int>& nums) {

            int ret=0,pre=0;

            for(int i=0;i<nums.size();i++){

                if(nums[i] == 1){

                    pre = pre + 1;

                    if(pre>ret){

                        ret = pre;

                    }

                }

                else{

                    pre = 0;

                }

            }

            return ret;

        }

    };

  • #C++ Day44 Basic Data Structure Chapter3  review-2 & Sequential list version 3.0 December 31 2025

    //Sequential list version 3.0

    #include <iostream>

    using namespace std;

    #define eleType int

    //1.define a structure

    struct SequentialList {

    eleType* elements;

    int capacity;

    int size;

    };

    //2.initialize

    void initializeList(SequentialList* list, int capacity) {

    list->elements = new eleType[capacity];

    list->capacity = capacity;

    list->size = 0;

    }

    //3.destroy

    void destroyList(SequentialList* list) {

    delete[] list->elements;

    list->elements = nullptr;

    list->size = 0;

    list->capacity = 0;

    }

    //4.size and is it empty

    int sizeOfList(SequentialList* list) {

    return list->size;

    }

    bool isEmpty(SequentialList* list) {

    return list->size == 0;

    }

    //5.insert

    void insertElement(SequentialList* list, int index,eleType element) {

    if (index<0 || index>list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->capacity == list->size) {

    int newcapacity =(list->capacity==0) ? 4 : list->capacity * 2;

    eleType* newlist = new eleType[newcapacity];

    for (int i = 0; i < list->size; i++) {

    newlist[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = newlist;

    list->capacity = newcapacity;

    }

    for (int i = list->size; i > index; i–) {

    list->elements[i] = list->elements[i – 1];

    }

    list->elements[index] = element;

    list->size++;

    }

    //6.delete

    void deleteElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    for (int i = index; i < list->size – 1; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    //7.findindex

    int findIndex(SequentialList* list, eleType element) {

    for(int i=0;i<list->size;i++){

    if (list->elements[i] == element) {

    return i;

    }

    }

    return -1;

    }

    //8.get

    eleType getElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    //9.update

    void updateElement(SequentialList* list, int index, eleType element) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = element;

    }

    int main() {

    SequentialList mylist;

    int capa=10;

    initializeList(&mylist, capa);

    cout << “isEmpty:” << isEmpty(&mylist)<<endl;

    cout << “size:” << sizeOfList(&mylist) << endl;

    for (int i = 0; i < capa; i++) {

    insertElement(&mylist, i, i * 10);

    }

    cout << “isEmpty:” << isEmpty(&mylist) << endl;

    cout << “size:” << sizeOfList(&mylist) << endl;

    for (int i = 0; i < sizeOfList(&mylist); i++) {

    cout << getElement(&mylist, i) << ‘ ‘;

    }cout << endl;

    insertElement(&mylist,3, 5050);

    for (int i = 0; i < sizeOfList(&mylist); i++) {

    cout << getElement(&mylist, i) << ‘ ‘;

    }cout << endl;

    cout << “isEmpty:” << isEmpty(&mylist) << endl;

    cout << “size:” << sizeOfList(&mylist) << endl;

    int id = findIndex(&mylist, 50);

    if (id != -1) {

    cout << “Found:” << getElement(&mylist, id) << endl;

    deleteElement(&mylist, id);

    }

    else {

    cout << “Not found!” << endl;

    }

    for (int i = 0; i < sizeOfList(&mylist); i++) {

    cout << getElement(&mylist, i) << ‘ ‘;

    }cout << endl;

    cout << “isEmpty:” << isEmpty(&mylist) << endl;

    cout << “size:” << sizeOfList(&mylist) << endl;

    updateElement(&mylist, 5, 9090);

    for (int i = 0; i < sizeOfList(&mylist); i++) {

    cout << getElement(&mylist, i) << ‘ ‘;

    }cout << endl;

    cout << “isEmpty:” << isEmpty(&mylist) << endl;

    cout << “size:” << sizeOfList(&mylist) << endl;

    destroyList(&mylist);

    for (int i = 0; i < sizeOfList(&mylist); i++) {

    cout << getElement(&mylist, i) << ‘ ‘;

    }cout << endl;

    cout << “isEmpty:” << isEmpty(&mylist) << endl;

    cout << “size:” << sizeOfList(&mylist) << endl;

    return 0;

    }

  • #C++ Day43 Basic Data Structure Chapter3  review December 20 2025

    为什么不写&mylist.size-1

    因为 deleteElement 的第二个参数要的是 int 下标,不是“地址”。

    你的函数声明是:

    void deleteElement(SequentialList* list, int index)

    • 第 1 个参数 SequentialList*:要传顺序表的地址,所以要写 &mylist
    • 第 2 个参数 int index:要传下标这个数字,所以要写 mylist.size – 1

    你写 &mylist.size-1 会发生什么?

    先看运算优先级:. 的优先级比 & 高,所以

    &mylist.size-1

    等价于:

    (& (mylist.size)) – 1

    也就是说:

    1. & (mylist.size) 取的是 size 这个成员变量本身的地址,类型是 int*
    2. 然后 – 1 是指针运算,得到另一个地址(仍然是 int*)

    结果类型是 int*,而函数需要的是 int,类型完全不匹配,编译就会报错。

    更关键的一点:就算语法上能传进去,也没意义

    deleteElement 需要的是“要删哪个位置”的编号,例如 9、19、0。
    而 &mylist.size 是“size 这个整数在内存里放在哪儿”的地址,它跟“最后一个元素的下标”不是一回事。

    所以正确写法只能是:

    deleteElement(&mylist, mylist.size – 1);

    如果你想试试验证,可以把 &mylist.size 打印出来(作为地址)看看,它会是类似 0x7ffee… 这种,不可能是合理的下标数字。

    你现在这个“怎么办”,有两条路选,取决于你想不想让程序在 destroyList 之后还继续“安全地用这个表”。

    方案 A:不改代码(只改用法)

    你的代码里 destroyList 的语义就是:释放底层数组
    所以你要遵守一条规则:

    调用 destroyList(&mylist); 之后,就不要再把 mylist 当成可用的顺序表来用。
    只能结束程序,或者重新 initializeList 之后再用。

    也就是说,你这段:

    destroyList(&mylist);

    cout << isEmpty(&mylist) << endl;

    cout << sizeOfList(&mylist) << endl;

    从“概念上”是不合理的,因为 destroy 之后这个结构体已经处于“被销毁但还没重建”的状态。
    (它的 size 还在,但 elements 指向的内存已经没了。)

    如果你只是想“验证 destroy 后发生了什么”,你可以打印 size,但要理解:这不是一个可用状态

    方案 B:让 destroy 后变成“干净的空表”(需要改一小点)

    你现在的问题本质是:destroy 只 delete[],但没有把 elements/size/capacity 变成一个“明确的无效/空状态”。

    你可以让 destroyList 在释放后把它清空:

    void destroyList(SequentialList* list) {

        delete[] list->elements;

        list->elements = nullptr;

        list->capacity = 0;

        list->size = 0;

    }

    这样 destroy 之后:

    • sizeOfList 会返回 0
    • isEmpty 会返回 true
    • 并且 elements=nullptr 也能避免“误用旧指针”和“重复 destroy 导致二次释放”的风险

    注意:这并不等于“还能继续 insert/get”。
    如果你要继续用,仍然要先 initializeList 重新分配数组。

    你现在该怎么选?

    • 你只是写作业/练习生命周期:选 A,destroy 后不再使用它。
    • 你希望 destroy 后状态更合理、更不容易踩坑:选 B,destroy 后顺便把成员重置。

    你想要的是哪一种:destroy 后彻底不能用(A),还是 destroy 后变成“空壳”但要重新初始化才能用(B)?我可以按你选的那种,帮你把“正确的使用顺序”用你 main 里的流程给你标出来。

    nullptr

    nullptr 是 C++11 引入的一个关键字,表示**“空指针”**:也就是“这个指针不指向任何有效对象/内存”。

    在你的结构体里:

    eleType* elements;

    elements 是一个指针。你 destroyList 里 delete[] list->elements; 之后,这个指针还保存着旧地址,但那块内存已经释放了,此时它变成了“悬空指针”(dangling pointer)。这很危险,因为你之后如果再用它,会访问到已经无效的内存。

    所以常见习惯是释放后把它设为空指针:

    list->elements = nullptr;

    这样做的意义:

    1. 明确状态:告诉自己/别人:这张表现在没有有效数组了
    2. 避免误用:以后如果不小心用 elements,至少能更容易发现问题(比如你可以先判断是不是 nullptr)
    3. 防止重复释放:如果你不小心又调用一次 destroyList,delete[] nullptr; 是安全的(不会崩)

    nullptrNULL / 0 有什么区别?

    • NULL 在很多实现里其实就是 0 或 0L,本质是整数,容易引发重载歧义。
    • nullptr 是专门的“空指针类型”(std::nullptr_t),只用于指针,更安全。

    所以 C++ 里推荐用 nullptr,别用 NULL。

    你在当前代码里,nullptr 应该怎么理解?

    如果你将来(概念上)让 destroy 后做:

    list->elements = nullptr;

    就等于把 elements 变成“没有指向任何数组”的状态。

    注意:nullptr 只适用于指针成员(比如 elements),不适用于 size/capacity 这种 int。

    如果你愿意,我也可以结合你这份代码,告诉你“什么时候 elements 该是 nullptr,什么时候不该是 nullptr”,这样你更容易判断顺序表现在是不是可用状态。

    #include <iostream>

    using namespace std;

    #define eleType int

    //1.define

    struct SequentialList {

    eleType* elements;

    int capacity;

    int size;

    };

    //2.initialize

    void initializeList(SequentialList* list, int capacity) {

    list->elements = new eleType[capacity];

    list->capacity = capacity;

    list->size = 0;

    }

    //3.destroy

    void destroyList(SequentialList* list) {

    delete[] list->elements;

    list->elements = nullptr; //c++11里面引入的一个关键字 等于把elements变成没有指向任何数组的状态 nullptr只适用于像elements这种指针成员 不适用于 size/capacity 这种int

    list->size = 0;

    list->capacity = 0;

    //置空

    }

    //4.isempty and size

    bool isEmpty(SequentialList* list) {

    return list->size == 0;

    }

    int sizeOfList(SequentialList* list) {

    return list->size;

    }

    //5.insert

    void insertElement(SequentialList* list,int index,eleType element){

    if (index<0 || index>list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->capacity == list->size) {

    int newcapacity = list->capacity * 2;

    eleType* newlist = new eleType[newcapacity]; //返回值是这个new数组的首地址 所以写eleType * newlist

    for (int i = 0; i < list->size; i++) {

    newlist[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = newlist;

    list->capacity = newcapacity;

    }

    /*list->size++;

    for (int i = list->size-1; i >index ; i–) {

    list->elements[i + 1] = list->elements[i];

    }

    list->elements[index] = element;*/ // 有BUG 插入函数的数据吞噬漏洞

    for (int i = list->size; i > index; i–) {

    list->elements[i] = list->elements[i – 1];

    }

    list->elements[index] = element;

    list->size++;

    }

    //6.delete

    void deleteElement(SequentialList* list, int index) {

    if(index<0||index >= list->size){

    throw std::invalid_argument(“invalid index”);

    }

    /*for (int i = index; i < list->size; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;*///有数组越界 bug list->size-1才对 不然读size可能会读到其他值例如密码

    for (int i = index; i < list->size-1; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    //7.find

    int findElementIndex(SequentialList* list, eleType element) {

    for (int i = 0; i < list->size; i++) {

    if (list->elements[i] == element) {

    return i;

    }

    }

    return -1;

    }

    //8.get

    eleType getElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    //9.update

    void updateElement(SequentialList* list, int index, eleType value) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = value;

    }

    int main() {

    SequentialList mylist;

    int mycapacity=10;

    initializeList(&mylist, mycapacity);

    cout << “IsEmpty:” << isEmpty(&mylist)<<endl;

    cout << “Size:” <<sizeOfList(&mylist) << endl;//初始化时 size是置于零的 所以没有size

    for (int i = 0; i < mycapacity; i++) {

    insertElement(&mylist, i, i * 10);

    }

    cout << “IsEmpty:” << isEmpty(&mylist) << endl;

    cout << “Size:” << sizeOfList(&mylist) << endl;

    for (int i = 0; i < sizeOfList(&mylist); i++) {

    cout << getElement(&mylist, i) << ‘ ‘;

    }cout << endl;

    int myindex = findElementIndex(&mylist, 50);

    updateElement(&mylist,myindex,520);

    for (int i = 0; i < sizeOfList(&mylist); i++) {

    cout << getElement(&mylist, i) << ‘ ‘;

    }cout << endl;

    int i = 10;

    while(i){

    insertElement(&mylist, sizeOfList(&mylist), 555);

    i–;

    }

    for (int i = 0; i < sizeOfList(&mylist); i++) {

    cout << getElement(&mylist, i) << ‘ ‘;

    }cout << endl;

    deleteElement(&mylist, mylist.size-1);

    for (int i = 0; i < sizeOfList(&mylist); i++) {

    cout << getElement(&mylist, i) << ‘ ‘;

    }cout << endl;

    cout << “IsEmpty:” << isEmpty(&mylist) << endl;

    cout << “Size:” << sizeOfList(&mylist) << endl;

    deleteElement(&mylist, 2);

    insertElement(&mylist, 0, 5);

    for (int i = 0; i < sizeOfList(&mylist); i++) {

    cout << getElement(&mylist, i) << ‘ ‘;

    }cout << endl;

    cout << “IsEmpty:” << isEmpty(&mylist) << endl;

    cout << “Size:” << sizeOfList(&mylist) << endl;

    destroyList(&mylist);

    cout << “IsEmpty:” << isEmpty(&mylist) << endl;

    cout << “Size:” << sizeOfList(&mylist) << endl;

    return 0;

    }

  • #C++ Day42 Basic Data Structure Chapter3  review December 18 2025

    要理解为什么SequentialList myList;不用加*,需要从变量的类型本质内存存储方式以及函数参数的设计意图三个层面来分析:

    一、先明确两个核心概念:普通变量 vs 指针变量

    C++ 中变量的声明决定了它的内存形态使用方式

    1. SequentialList myList;:声明结构体的实际实例(普通变量)

    • 这行代码在栈内存中创建了一个SequentialList类型的完整实例,它本身占据实际的内存空间,包含三个成员:
      • eleType* elements(指针成员)
      • int capacity(整型成员)
      • int size(整型成员)
    • 你可以直接通过点运算符(.)访问它的成员(比如myList.size),也可以通过&myList获取它的内存地址(这是一个SequentialList*类型的指针)。

    2. SequentialList* myList;:声明指向结构体的指针变量

    • 这行代码只在栈内存中创建了一个指针变量(大小通常为 4/8 字节,取决于系统),它的作用是存储一个内存地址,但本身并不是结构体实例
    • 此时myList是一个野指针(初始值随机),它没有指向任何有效的SequentialList实例。如果直接使用myList->capacity,会访问非法内存,导致程序崩溃。
    • 若要使用指针,必须先为它分配有效的实例,比如:cpp

      运行




      SequentialList* myList = new SequentialList(); // 堆上创建结构体实例,指针指向该实例




    二、结合代码中函数的参数设计分析

    代码中的函数(如initializeList、insertElement等)的参数都是SequentialList* list(结构体指针),这是为了实现对原结构体实例的修改(C++ 函数参数默认是值传递,传指针可以避免拷贝,且能修改原变量)。

    但这并不意味着我们必须声明指针变量,因为:

    • 对于普通变量myList,我们可以通过&myList(取地址运算符)获取它的地址,这个地址的类型正好是SequentialList*,可以直接传给函数。
      比如:initializeList(&myList, 10); 就是把myList的地址传给initializeList的list参数,函数内部通过指针list操作的就是外部的myList实例。

    如果我们声明的是指针变量SequentialList* myList;,反而需要额外的初始化步骤(否则是野指针),这会增加代码的复杂度,而这里完全没有必要。

    三、两种写法的内存对比

    写法内存位置是否是有效实例函数调用方式内存管理
    SequentialList myList;是(完整实例)initializeList(&myList, 10);栈内存由系统自动释放
    SequentialList* myList;栈(指针)否(野指针)需先myList = new SequentialList();,再initializeList(myList, 10);堆内存需手动delete myList;

    四、总结:为什么这里不用加*

    • 需求是 “结构体实例” 而非 “指针”:我们需要的是一个能存储capacity、size和elements的实际结构体对象,而SequentialList myList;直接创建了这个对象,满足需求。
    • 传地址即可适配指针参数:函数需要SequentialList*参数,通过&myList取普通变量的地址,就能完美匹配参数类型,无需额外声明指针变量。
    • 避免野指针风险:如果声明SequentialList* myList;而不初始化,会导致野指针,引发程序崩溃;而普通变量是栈上的有效实例,无此风险。

    拓展:如果非要用指针怎么办?

    如果坚持用SequentialList* myList;,代码需要修改为:

    cpp

    运行

    // 声明指针并在堆上创建实例

    SequentialList* myList = new SequentialList();

    // 调用函数(直接传指针,无需&)

    initializeList(myList, 10);

    // … 其他操作 …

    // 不仅要释放elements,还要释放结构体本身

    destroyList(myList);

    delete myList; // 释放堆上的SequentialList实例

    这种写法更复杂,且容易忘记delete myList导致内存泄漏,因此原代码的写法更简洁、安全。

    当顺序表的容量已满时,需要进行…-知识星球

    Chen 提问:

    为什么这个地方是capacity*2而不是capacity++

    当顺序表的容量已满时,需要进行扩容。扩容的方式是将容量扩大为原来的两倍,即 L->capacity * 2。这样做的原因是为了减少频繁扩容的次数,提高顺序表的性能。 因为扩容操作本身需要将所有元素重新进行一次拷贝,时间复杂度 O(n),如果每次扩容只是将容量增加1,那么当顺序表中的元素数量不断增加时,扩容的次数会非常频繁,从而导致性能下降。而将容量扩大为原来的两倍,可以有效地减少扩容的次数,确保算上扩容以后,均摊时间复杂度为 O(1),提高顺序表的效率。 为了均摊时间复杂度是O(1)呢? 某一次内存重分配完了以后, Capacity 达到了 n,那么表示这里有 n/2 个位置的元素是空的,剩下 n/2 的一半元素被拷贝了1次,剩下的一半的一半的元素拷贝了2次,… 那么所有元素被拷贝的次数就是: n/4 * 1 + n/8 * 2 + n/16 * 4 + … = n 所以当插入 n 个元素后,拷贝的总时间复杂度就是 O(n),每个元素的均摊时间复杂度就是 O(1)。  试着用最简单的语言解释

    已完成思考

    我们用生活化的例子 + 最直白的计算,把这个问题拆成两部分讲清楚:

    一、先搞懂:为什么不选capacity++(每次只加 1)?

    假设顺序表的扩容是 “满了就加 1”,把这个过程想象成搬仓库

    • 你有个小仓库,只能放 1 个箱子(容量 1),放满后,要换能放 2 个的仓库,得把1 个箱子搬过去(拷贝 1 个元素);
    • 再放 1 个,仓库又满了,换能放 3 个的仓库,得把2 个箱子搬过去(拷贝 2 个元素);
    • 再放 1 个,又满了,换能放 4 个的仓库,得把3 个箱子搬过去(拷贝 3 个元素);
      ……
      直到仓库能放n个箱子,你总共搬了1+2+3+…+(n-1)次箱子,这个总数约等于n²/2(比如 n=100,就要搬约 5000 次)。

    简单说:每次只加 1,扩容太频繁,搬箱子(拷贝元素)的总次数会爆炸式增长,性能差到没法用。

    二、再理解:为什么选capacity*2(每次扩 2 倍)?

    还是用搬仓库的例子,这次满了就换2 倍大的仓库:

    • 初始仓库能放 1 个,放满后换能放 2 个的,搬1 个箱子;
    • 放满 2 个后,换能放 4 个的,搬2 个箱子;
    • 放满 4 个后,换能放 8 个的,搬4 个箱子;
    • 放满 8 个后,换能放 16 个的,搬8 个箱子;
      ……
      直到仓库能放n个箱子,你总共搬了1+2+4+8+…次,这个总数永远小于 n(比如 n=16,只搬了 1+2+4+8=15 次;n=32,只搬了 31 次)。

    核心差异:2 倍扩容让 “搬仓库” 的次数极少,总搬箱次数和最终的箱子数差不多

    三、最后说:为什么均摊时间复杂度是 O (1)?

    “均摊时间复杂度” 就是把所有搬箱子的耗时,平摊到每一次 “放箱子” 的操作上,看平均每次放箱子要花多少时间。

    举个具体例子:插入 8 个元素(箱子),用 2 倍扩容:

    • 插入第 1 个:仓库满了,扩容到 2,搬 1 个箱子(总耗时:1 次插入 + 1 次搬);
    • 插入第 2 个:仓库满了,扩容到 4,搬 2 个箱子(总耗时:1 次插入 + 2 次搬);
    • 插入第 3、4 个:不用扩容(总耗时:2 次插入);
    • 插入第 4 个后满了,扩容到 8,搬 4 个箱子(总耗时:1 次插入 + 4 次搬);
    • 插入第 5-8 个:不用扩容(总耗时:4 次插入)。

    总耗时统计

    • 插入操作:8 次(每个元素 1 次);
    • 搬箱子(拷贝):1+2+4=7 次;
    • 总计:8+7=15 次操作。

    平均到每个元素:15÷8≈1.875 次操作 —— 这个数是固定的常数(不管插入多少元素,平均下来每次都接近 1 次操作),这就是均摊时间复杂度 O (1)

    一句话总结

    每次扩容 2 倍,虽然偶尔有一次插入要 “搬很多箱子”,但把这个耗时平摊到很多次不用搬的插入上,平均下来每次插入的耗时几乎不变;而每次只加 1,每插一次都要 “搬箱子”,越往后越慢。

    剩下 n/2 的一半元素被拷贝了1次,剩下的一半的一半的元素拷贝了2次、

    已完成思考

    我们用具体的数值例子(比如最终容量 n=8) + 直白的分组,把这句话拆解得明明白白,保证一看就懂:

    先明确前提(原文的场景)

    某次扩容后容量达到 n(比如 n=8),因为是翻倍扩容,这次扩容是从n/2=4扩容到n=8的。

    所以扩容后:

    • 总容量n=8,其中元素数量是 n/2=4(都是从旧数组拷贝过来的);
    • 剩下的n/2=4个位置是空的(这就是原文里 “这里有 n/2 个位置的元素是空的”)。

    我们要统计的是:这 4 个元素(n/2)从被插入到现在,一共被拷贝了多少次

    再拆解 “一半元素被拷贝 1 次,一半的一半拷贝 2 次……”

    以n=8(容量)、n/2=4(元素数)为例:

    把这 4 个元素按 **“加入顺序” 分组 **,看每组被拷贝的次数:

    分组(元素数量)对应原文的描述被拷贝的次数具体解释
    2 个元素(4 的一半)n/2 的一半(n/4=2)1 次这 2 个元素是在容量 4 时加入的,只经历了 “4→8” 这 1 次扩容,所以只被拷贝 1 次。
    1 个元素(4 的一半的一半)n/2 的一半的一半(n/8=1)2 次这个元素是在容量 2 时加入的,经历了 “2→4” 和 “4→8”2 次扩容,所以被拷贝 2 次。
    1 个元素(继续拆分)n/2 的一半的一半的一半3 次这个元素是在容量 1 时加入的,经历了 “1→2”“2→4”“4→8”3 次扩容,所以被拷贝 3 次。

    如果把容量放大到n=16(更易观察规律),规律会更明显:

    • 扩容后容量 n=16,元素数 n/2=8;
    • 4 个元素(8 的一半):在容量 8 时加入,只经历 “8→16”,被拷贝 1 次;
    • 2 个元素(8 的一半的一半):在容量 4 时加入,经历 “4→8”“8→16”,被拷贝 2 次;
    • 1 个元素(8 的一半的一半的一半):在容量 2 时加入,经历 3 次扩容,被拷贝 3 次;
    • 1 个元素:在容量 1 时加入,经历 4 次扩容,被拷贝 4 次。

    一句话翻译这句话的核心

    “越早期加入的元素,被拷贝的次数越多;每往回追溯一次扩容,元素数量就减半,拷贝次数就加 1”

    最后补一句:为什么总拷贝次数加起来约等于 n?

    还是以 n=8 为例,总拷贝次数是:

    2个×1次 + 1个×2次 + 1个×3次 = 2+2+3=7 ≈8(n)

    以 n=16 为例,总拷贝次数是:

    4个×1次 + 2个×2次 + 1个×3次 + 1个×4次 =4+4+3+4=15≈16(n)

    这就是原文里 “所有元素被拷贝的次数加起来等于 n” 的原因,最终平摊到每个元素上,拷贝的平均次数就是常数级(O (1))。

    #include <iostream>

    using namespace std;

    #define eleType int

    //1.define

    struct SequentialList {

    eleType* elements;

    int capacity;

    int size;

    };

    //2.initialize

    void initializeList(SequentialList* list, int capacity) {

    list->elements = new eleType[capacity];

    list->capacity = capacity;

    list->size = 0;

    }

    //3.isEmpty and size

    bool isEmpty(SequentialList* list) {

    return list->size == 0;

    }

    int sizeOfList(SequentialList* list) {

    return list->size;

    }

    //4.destroy

    void destroyList(SequentialList* list) {

    delete[] list->elements;

    }

    //5.insert

    void insertElement(SequentialList* list, int index, eleType element) {

    if (index<0 || index>list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->size == list->capacity) {

    int Newcapacity = list->capacity * 2;

    eleType* Newlist = new eleType[Newcapacity];

    for (int i = 0; i < list->size; i++) {

    Newlist[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = Newlist;

    list->capacity = Newcapacity;

    }

    list->size++;//size要放上面

    for (int i = list->size-1; i > index; i–) {//这里是list->size-1

    list->elements[i] = list->elements[i – 1]; 

    }

    list->elements[index] = element;

    }

    //6.delete

    void deleteElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    for (int i = index; i < list->size-1; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    //7.find index

    int findElementIndex(SequentialList* list, eleType element) {

    for (int i = 0; i < list->size; i++) {

    if (list->elements[i] == element) {

    return i;

    }

    }

    return -1;//represent not found

    }

    //8.getElement with index

    eleType getElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    //9.update

    void updateElement(SequentialList* list, int index, eleType element) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = element;

    }

    int main() {

    SequentialList Mylist;

    int list_capacity = 10;

    initializeList(&Mylist, list_capacity);

    cout << “IsEmpty:” << isEmpty(&Mylist) << endl;

    cout << “Size:” << sizeOfList(&Mylist) << endl;

    for (int i = 0; i < list_capacity; i++) {

    insertElement(&Mylist, i, i * 10);

    }

    cout << “IsEmpty:” << isEmpty(&Mylist) << endl;

    cout << “Size:” << sizeOfList(&Mylist)<<endl;

    for (int i = 0; i < sizeOfList(&Mylist); i++) {

    cout << getElement(&Mylist, i) << ” “;

    }cout << endl;

    deleteElement(&Mylist, 9);

    cout << “IsEmpty:” << isEmpty(&Mylist) << endl;

    cout << “Size:” << sizeOfList(&Mylist) << endl;

    for (int i = 0; i < sizeOfList(&Mylist); i++) {

    cout << getElement(&Mylist, i) << ” “;

    }cout << endl;

    insertElement(&Mylist, sizeOfList(&Mylist), 55);

    for (int i = 0; i < sizeOfList(&Mylist); i++) {

    cout << getElement(&Mylist, i) << ” “;

    }cout << endl;

    int idx = findElementIndex(&Mylist, 55);

    updateElement(&Mylist, idx, 520);

    for (int i = 0; i < sizeOfList(&Mylist); i++) {

    cout << getElement(&Mylist, i) << ” “;

    }cout << endl;

    cout << “IsEmpty:” << isEmpty(&Mylist) << endl;

    cout << “Size:” << sizeOfList(&Mylist) << endl;

    destroyList(&Mylist);

    return 0;

    }

  • #C++ Day41 Basic Data Structure Chapter3  December 17 2025

    核心结论:这两步是 “先声明指针(留位置),再动态分配内存(找空间)”,缺一不可,用通俗的话拆解:

    1. eleType* elements; —— 声明“地址容器”

    • 作用:在顺序表结构体里,预留一个“存放内存地址”的位置(就像在手机里建一个“文件夹快捷方式”,但还没指向实际文件夹)。

    • 为什么必须有?:顺序表需要连续的存储空间存数据,但一开始不知道要存多少个元素(容量由用户初始化时指定),不能直接定义固定大小的数组(比如eleType elements[100]),所以用指针先“占个坑”,后续再指向实际的内存空间。

    2. list->elements = new eleType[capacity]; —— 分配“实际储物间”

    • 作用:用new关键字,根据用户指定的capacity(容量),向电脑申请一块 连续的、能存capacity个eleType类型数据的内存空间(相当于根据需求,实际创建一个“储物间”),然后把这个“储物间”的地址,赋值给前面声明的elements指针(让“快捷方式”指向真实文件夹)。

    • 为什么要这么写?:如果只声明指针不分配内存,elements就是个“野指针”(指向随机地址),往里面存数据会导致程序崩溃;只有通过new申请了具体空间,才能安全存元素。

    一句话总结:

    eleType* elements; 是“告诉程序:我要一个能存数据的地址”,list->elements = new eleType[capacity]; 是“给程序实际找一块能存capacity个数据的地方,并把地址记下来”,两者配合才能让顺序表拥有可使用的存储空间。

    需要我用生活案例再类比一遍,或者补充new分配内存后如何释放(避免内存泄漏)吗?

    核心结论:SequentialList* list 里的 * 表示 list 是一个指针,作用是让函数能直接操作「主程序里的原顺序表」,而不是复制一个没用的副本——用通俗的类比就能秒懂:

    1. 先搞懂:* 在这里的意思

    • SequentialList 是你定义的“顺序表结构体”(像一个“文件柜”,装着 elements 指针、capacity 容量、size 长度这3个“抽屉”);

    • SequentialList* list 里的 * 告诉编译器:list 不是一个完整的“文件柜”,而是指向这个文件柜的钥匙(存着文件柜的地址)。

    2. 为什么非要传“钥匙”(指针),不能直接传“文件柜”?

    如果函数参数写成 void initializeList(SequentialList list, int capacity)(没有 *),相当于:

    • 你把家里的文件柜(原顺序表)复制了一个一模一样的假柜子,送到函数里;

    • 函数在假柜子上“分配内存”“设置容量”(比如 list.capacity = capacity),改的全是假柜子;

    • 函数结束后假柜子被扔掉,家里的原柜子还是空的、没初始化——等于白忙活!

    而传 SequentialList* list(带 * 的指针),相当于:

    • 你把家里文件柜的钥匙交给函数;

    • 函数用钥匙打开原柜子,直接在原柜子里操作:给 elements 抽屉分配内存(new)、设置 capacity 和 size;

    • 函数结束后,原柜子已经被初始化好,能直接用——这才是我们要的效果!

    3. 代码里的 list-> 也和 * 有关

    因为 list 是“钥匙”(指针),不是直接的“文件柜”,所以不能用 . 访问成员(比如 list.elements 会报错),必须用 -> 表示“通过钥匙找到文件柜,再打开抽屉”:

    • list->elements = new eleType[capacity] → 用钥匙找到原柜子,给 elements 抽屉分配内存;

    • list->capacity = capacity → 用钥匙找到原柜子,给 capacity 抽屉赋值。

    一句话总结:

    参数里的 * 是为了让函数“直达原顺序表”,能修改它的内部数据(分配内存、设容量);如果没有 *,函数改的是副本,原顺序表永远初始化失败。

    需要我用“传指针”和“不传指针”的代码对比,再演示一次区别吗?

    核心原因:参数名和成员名要“各司其职”——elements 已经是“表内元素数组”的名字,参数名如果也叫 elements,会混淆“整个顺序表”和“表内数据”的指代,还会让代码语义混乱,用通俗的话讲:

    1. 先明确:两者指代的是完全不同的东西

    • 成员名 elements:是顺序表结构体里的“零件”——专门存数据的数组(比如文件柜里的“文件夹”,只负责装1、2、3这些具体数据);

    • 参数名(原本的 list):是指向“整个顺序表”的指针(比如文件柜的“钥匙”,负责操控整个柜子,包括文件夹、容量标签、当前存放数量)。

    如果参数也叫 elements,就相当于把“文件柜的钥匙”和“柜子里的文件夹”叫同一个名字——别人看代码会完全懵:“这个 elements 到底是指整个柜子,还是柜子里的文件夹?”

    2. 举个错误示例:参数叫 elements 会多混乱

    如果真把参数改成 elements,代码会变成这样:

    // 错误示例:参数名和成员名重名

    void initializeList(SequentialList* elements, int capacity) {

        elements->elements = new eleType[capacity];  // 救命!两个elements挤在一起

        elements->capacity = capacity;

    }

    这句话 elements->elements 翻译过来是:“用‘文件夹’(参数名)找到整个文件柜,再打开柜子里的‘文件夹’(成员名)”——逻辑上完全说不通,不仅别人看不懂,未来的你回头看代码也会疑惑:“我当初到底想指哪个?”

    3. 命名的核心规矩:“一物一名”

    好的代码命名要满足“见名知义”,核心是“不同用途的东西,名字不能重”:

    • 指代“整个顺序表”的指针:用 list、seqList、sl 等,明确是“整体”;

    • 指代“表内数据数组”的成员:用 elements、data 等,明确是“局部零件”;

    • 两者如果重名,就打破了“一物一名”的规则,导致语义冲突。

    一句话总结:

    不是不能叫 elements,而是这个名字已经被“表内的元素数组”占用了,参数需要一个“指代整个顺序表”的专属名字,才能区分“整体”和“局部”,让代码逻辑清晰不混乱。

    需要我帮你整理一份“顺序表完整操作代码”(包含初始化、插入、删除),全程用规范命名(参数名 seqList + 成员名 elements),帮你巩固这个逻辑吗?

    #include <iostream>

    using namespace std;

    #define eleType int

    struct SequentialList {

    eleType* elements;//一个能存数据的地址

    int capacity;

    int size;

    };

    void initializeList(SequentialList* list, int capacity) {

    list->elements = new eleType[capacity];//给程序实际找一个能存capacity个数据的地址。并把地址记下来

    list->capacity = capacity;

    list->size = 0;

    }

    bool isEmpty(SequentialList* list) {

    return list->size == 0;

    }

    int sizeOfList(SequentialList* list) {

    return list->size;

    }

    void destroyList(SequentialList* list) {

    delete[] list->elements;

    }

    void insertElement(SequentialList* list,int index,eleType element){

    if (index<0 || index>list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->size == list->capacity) {

    int newCapacity = list->capacity * 2;

    eleType* newList = new eleType[newCapacity];

    for (int i = 0; i < list->size; ++i) {

    newList[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = newList;

    list->capacity = newCapacity;

    }

    for (int i = list->size; i > index; i–) {

    list->elements[i] = list->elements[i – 1];

    }

    list->elements[index] = element;

    list->size++;

    }

    void deleteElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    for (int i = index; i < list->size; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    int findElement(SequentialList* list, eleType element) {

    for (int i= 0; i < list->size; i++) {

    if (list->elements[i] == element) {

    return i;

    }

    }

    return -1;

    }

    eleType getElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    void updateElement(SequentialList* list, int index, eleType value) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = value;

    }

    int main() {

    SequentialList myList;

    initializeList(&myList, 10);

    for (int i = 0; i < 10; i++) {

    insertElement(&myList, i, i * 10);

    }

    cout << “Size:” << sizeOfList(&myList) << endl;

    cout << “Is empty:” << isEmpty(&myList) << endl;

    for (int i = 0; i < sizeOfList(&myList); i++){

    cout << getElement(&myList, i) << ” “;

    }

    cout << endl;

    deleteElement(&myList, 3);

    for (int i = 0; i < sizeOfList(&myList); i++) {

    cout << getElement(&myList, i) << ” “;

    }

    cout << endl;

    updateElement(&myList, 1, 1314);

    for (int i = 0; i < sizeOfList(&myList); i++) {

    cout << getElement(&myList, i) << ” “;

    }

    cout << endl;

    int idx = findElement(&myList, 20);

    updateElement(&myList, idx,520);

    for (int i = 0; i < sizeOfList(&myList); i++) {

    cout << getElement(&myList, i) << ” “;

    }

    cout << endl;

    cout << “Size:” << sizeOfList(&myList) << endl;

    cout << “Is empty:” << isEmpty(&myList) << endl;

    insertElement(&myList, sizeOfList(&myList), 21111);

    for (int i = 0; i < sizeOfList(&myList); i++) {

    cout << getElement(&myList, i) << ” “;

    }

    cout << endl;

    cout << “Size:” << sizeOfList(&myList) << endl;

    cout << “Is empty:” << isEmpty(&myList) << endl;

    insertElement(&myList, 4, 21111);

    for (int i = 0; i < sizeOfList(&myList); i++) {

    cout << getElement(&myList, i) << ” “;

    }

    cout << endl;

    cout << “Size:” << sizeOfList(&myList) << endl;

    cout << “Is empty:” << isEmpty(&myList) << endl;

    destroyList(&myList);

    return 0;

    }

  • #C++ Day40 Basic Data Structure Chapter3  November 26 2025

    青年歌手大奖赛_评委会打分 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 183698    Accepted Submission(s): 89947

    Problem Description 青年歌手大奖赛中,评委会给参赛选手打分。选手得分规则为去掉一个最高分和一个最低分,然后计算平均得分,请编程输出某选手的得分。  
    Input 输入数据有多组,每组占一行,每行的第一个数是n(2<n<=100),表示评委的人数,然后是n个评委的打分。  
    Output 对于每组输入数据,输出选手的得分,结果保留2位小数,每组输出占一行。  
    Sample Input 3 99 98 97 4 100 99 98 97  
    Sample Output 98.00 98.50  
    Author lcy  
    Source C语言程序设计练习(三)

    #include <iostream>

    using namespace std;

    #define eleType double

    #include <iomanip>

    //1.

    struct SequentialList {

    eleType* elements;

    int capacity;

    int size;

    };

    //2.initial

    void initializeList(SequentialList * list,int capacity){

    list->elements = new eleType[capacity];

    list->capacity = capacity;

    list->size = 0;

    }

    //3.Is Empty

    bool isEmpty(SequentialList* list) {

    return list->size == 0;

    }

    int sizeOfList(SequentialList* list) {

    return list->size;

    }

    //4.destroy

    void destroyList(SequentialList* list) {

    delete[] list->elements;

    }

    //5.insert

    void insertElement(SequentialList* list, int index, eleType element) {

    if (index < 0 || index > list->size)

    {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->size == list->capacity) {

    int newCapacity = list->capacity*2;

    eleType* newList = new eleType[newCapacity];

    for (int i = 0; i < list->size; ++i) {

    newList[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = newList;

    list->capacity = newCapacity;

    }

    for (int i = list->size; i > index; –i) {

    list->elements[i] = list->elements[i – 1];

    }

    list->elements[index] = element;

    list->size++;

    }

    //6.delete

    void deleteElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size)

    {

    throw std::invalid_argument(“invalid index”);

    }

    for (int i = index; i < list->size – 1; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    //7.find

    int findElementIndex(SequentialList* list, eleType element) {

    for (int i = 0; i < list->size; i++) {

    if (list->elements[i] == element) {

    return i;

    }

    }

    return -1;

    }

    //8.get

    eleType getElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size)

    {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    //9.update

    void updateElement(SequentialList* list, int index, eleType element) {

    if (index < 0 || index >= list->size)

    {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = element;

    }

    int main() {

    SequentialList s;

    int n;

    cout << setiosflags(ios::fixed) << setprecision(2);

    while (cin >> n && n > 2 && n <= 100) {

    initializeList(&s, 1);

    for (int i = 0; i < n; ++i) {

    eleType x;

    cin >> x;

    insertElement(&s,i,x);

    }

    double max= getElement(&s, 0), min=getElement(&s,0);

    for (int i = 1; i < n; ++i) {

    if(getElement(&s,i)<min) {

    min = getElement(&s, i);

    }

    if (getElement(&s, i) > max) {

    max = getElement(&s, i);

    }

    }

    int maxindex = findElementIndex(&s, max);

    deleteElement(&s, maxindex);

    int minindex = findElementIndex(&s, min);

    deleteElement(&s, minindex);

    double sum = 0;

    for (int i = 0; i < n – 2; ++i) {

    sum += getElement(&s, i);

    }

    double avg = 0;

    if (n – 2 == 1) {

    avg= getElement(&s, 0);

    }

    else{

    avg= sum / (n – 2);

    }

    cout << avg << endl;

    }

    return 0;

    }

  • #C++ Day39 Basic Data Structure Chapter3  November 25 2025

    //Basic Data Structure Day2 Vito’s Sequential List 5 review

    #include <iostream>

    using namespace std;

    #define eleType int

    //1.

    struct SequentialList {

    eleType* elements;

    int capacity;

    int size;

    };

    //2.initial

    void initializeList(SequentialList * list,int capacity){

    list->elements = new eleType[capacity];

    list->capacity = capacity;

    list->size = 0;

    }

    //3.Is Empty

    bool isEmpty(SequentialList* list) {

    return list->size == 0;

    }

    int sizeOfList(SequentialList* list) {

    return list->size;

    }

    //4.destroy

    void destroyList(SequentialList* list) {

    delete[] list->elements;

    }

    //5.insert

    void insertElement(SequentialList* list, int index, eleType element) {

    if (index < 0 || index > list->size)

    {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->size == list->capacity) {

    int newCapacity = list->capacity*2;

    eleType* newList = new eleType[newCapacity];

    for (int i = 0; i < list->size; ++i) {

    newList[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = newList;

    list->capacity = newCapacity;

    }

    for (int i = list->size; i > index; –i) {

    list->elements[i] = list->elements[i – 1];

    }

    list->elements[index] = element;

    list->size++;

    }

    //6.delete

    void deleteElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size)

    {

    throw std::invalid_argument(“invalid index”);

    }

    for (int i = index; i < list->size – 1; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    //7.find

    int findElementIndex(SequentialList* list, eleType element) {

    for (int i = 0; i < list->size; i++) {

    if (list->elements[i] == element) {

    return i;

    }

    }

    return -1;

    }

    //8.get

    eleType getElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size)

    {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    //9.update

    void updateElement(SequentialList* list, int index, eleType element) {

    if (index < 0 || index >= list->size)

    {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = element;

    }

    int main() {

    SequentialList myList;

    initializeList(&myList, 10);

    cout << “Size:” << sizeOfList(&myList)<<endl;

    cout << “isEmpty:” << isEmpty(&myList) << endl;

    for (int i = 0; i < myList.capacity; i++) {

    insertElement(&myList, i, i * 10);

    }

    cout << “Size:” << sizeOfList(&myList) << endl;

    cout << “isEmpty:” << isEmpty(&myList) << endl;

    for (int i = 0; i < myList.size; i++) {

    cout <<getElement(&myList, i)<<‘ ‘;

    }

    cout << endl;

    int idx = findElementIndex(&myList, 60);

    updateElement(&myList, idx, 1314);

    for (int i = 0; i < myList.size; i++) {

    cout << getElement(&myList, i) << ‘ ‘;

    }

    cout << endl;

    deleteElement(&myList, myList.size – 1);

    for (int i = 0; i < myList.size; i++) {

    cout << getElement(&myList, i) << ‘ ‘;

    }

    cout << endl;

    destroyList(&myList);

    return 0;

    }

  • C++ Vito’s 求奇数的乘积

    #include <iostream>

    using namespace std;

    #define eleType int

    struct SequentialList {

    eleType* elements;

    int size;

    int capacity;

    };

    void InitialList(SequentialList* list, int capacity) {

    list->elements = new eleType[capacity];

    list->size = 0;

    list->capacity = capacity;

    }

    void DestroyList(SequentialList* list) {

    delete[] list->elements;

    }

    bool IsEmpty(SequentialList* list) {

    return list->size == 0;

    }

    int Size(SequentialList* list) {

    return list->size;

    }

    void InsertElement(SequentialList* list, int index, eleType element) {

    if (index <0 || index > list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->size == list->capacity) {

    int Newcapacity = list->capacity * 2;

    eleType* NewList = new eleType[Newcapacity];

    for (int i = 0; i < list->size; i++) {

    NewList[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = NewList;

    list->capacity = Newcapacity;

    }

    for (int i = list->size; i > index; i–) {

    list->elements[i] = list->elements[i – 1];

    }

    list->elements[index] = element;

    list->size++;

    }

    void DeleteElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    for (int i = index; i < list->size – 1; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    eleType FindIndexOfElement(SequentialList* list, eleType element) {

    for (int i = 0; i < list->size; i++) {

    if (element == list->elements[i]) {

    return i;

    }

    }

    return -1;

    }

    int GetElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    void UpdateElement(SequentialList* list, int index, eleType element) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = element;

    }

    int main(){

    int n;

    SequentialList VitoList;

    while (cin >> n) {

    InitialList(&VitoList, 1);

    for (int i = 0; i < n; i++) {

    int x;

    cin >> x;

    InsertElement(&VitoList, i, x);

    }

    int prod = 1;

    for (int i = 0; i < VitoList.size; ++i) {

    int value = GetElement(&VitoList, i);

    if(value % 2 == 1){

    prod = value * prod;

    }

    }

    cout << prod <<endl;

    DestroyList(&VitoList);

    }

    return 0;

    }

  • #C++ Day36 Basic Data Structure Chapter2,3  November 22 2025

    //First completely wrote up all the code of sequential list

    #include <iostream>

    using namespace std;

    #define eleType int

    //1.define a structure

    struct SequentialList {

    eleType* elements;

    int size;

    int capacity;

    };

    //2.Initialize a list

    void InitializeList(SequentialList* list, int capacity) {

    list->elements = new eleType[capacity];

    list->size = 0;

    list->capacity = capacity;

    }

    //3.Destroy a list

    void DestroyList(SequentialList* list) {

    delete[] list->elements;

    }

    //4.IsEmpty and Size

    bool IsEmpty(SequentialList* list) {

    return list->size == 0;

    }

    int Size(SequentialList* list) {

    return list->size;

    }

    //5.Insert an element

    void InsertElement(SequentialList* list, int index, eleType element) {

    if (index<0 || index >list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->size == list->capacity) {

    int Newcapacity = list->capacity * 2;

    eleType* Newlist = new eleType[Newcapacity];

    for (int i = 0; i < list->size; i++) {

    Newlist[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = Newlist;

    list->capacity = Newcapacity;

    }

    for(int i=list->size;i>index;i–){

    list->elements[i] = list->elements[i – 1];

    }

    list->elements[index] = element;

    list->size++;

    }

    //6.delete an element

    void DeleteElement(SequentialList* list, int index) {

    if (index<0 || index >=list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    for (int i = index; i < list->size – 1; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    //7.find the index of an element

    int FindElementIndex(SequentialList* list, eleType element) {

    for (int i = 0; i < list->size; i++) {

    if (list->elements[i] == element) {

    return i;

    }

    }

    return -1;

    }

    //8.GetElement

    eleType GetElement(SequentialList* list, int index) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    //9.UpdateElement

    void UpdateElement(SequentialList* list, int index, eleType element) {

    if (index < 0 || index >= list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = element;

    }

    int main() {

    SequentialList VitoList;

    InitializeList(&VitoList, 10);

    for (int i = 0; i < 10; i++) {

    InsertElement(&VitoList, i, i * 10);

    }

    cout << “IsEmpty:” << IsEmpty(&VitoList)<<endl;

    cout << “Size:” << Size(&VitoList)<<endl;

    for (int i = 0; i < Size(&VitoList); i++) {

    cout << GetElement(&VitoList,i)<<” “;

    }

    cout << endl;

    InsertElement(&VitoList, 10, 520);

    for (int i = 0; i < Size(&VitoList); i++) {

    cout << GetElement(&VitoList, i) << ” “;

    }

    cout << endl;

    DeleteElement(&VitoList, 5);

    for (int i = 0; i < Size(&VitoList); i++) {

    cout << GetElement(&VitoList, i) << ” “;

    }

    cout << endl;

    int id=FindElementIndex(&VitoList, 70);

    cout << id << endl;

    UpdateElement(&VitoList, id, 666);

    for (int i = 0; i < Size(&VitoList); i++) {

    cout << GetElement(&VitoList, i) << ” “;

    }

    cout << endl;

    InsertElement(&VitoList, 10, 5566);

    for (int i = 0; i < Size(&VitoList); i++) {

    cout << GetElement(&VitoList, i) << ” “;

    }

    cout << endl;

    cout << “IsEmpty:” << IsEmpty(&VitoList) << endl;

    cout << “Size:” << Size(&VitoList) << endl;

    DestroyList(&VitoList);

    for (int i = 0; i < Size(&VitoList); i++) {

    cout << GetElement(&VitoList, i) << ” “;

    }

    cout << endl;

    return 0;

    }

  • #C++ Day36 Basic Data Structure Chapter3  November 21 2025

    //Vito’s Sequential List1 

    #include <iostream>

    using namespace std;

    #define DataType int

    //1.define a structure

    struct SequentialList {

    DataType *elements;

    int size;

    int capacity;

    };

    //2.initialize 

    void InitializeElement(SequentialList* list, int capacity) {

    list->elements = new DataType[capacity];

    list->size = 0;

    list->capacity = capacity;

    }

    //3.destroy

    void DestroyList(SequentialList* list) {

    delete[] list->elements;

    }

    //4.list’s number

    bool isEmpty(SequentialList* list) {

    return list->size == 0;

    }

    int size(SequentialList* list) {

    return list->size;

    }

    //5.insert

    void InsertElement(SequentialList* list,int index, DataType element) {

    if (index<0 || index > list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    if (list->size == list->capacity) {

    int newCapacity = list->capacity * 2;

    DataType* newElements = new DataType[newCapacity];

    for (int i = 0; i < list->size; i++) {

    newElements[i] = list->elements[i];

    }

    delete[] list->elements;

    list->elements = newElements;

    list->capacity = newCapacity;

    }

    for (int i = list->size; i > index; i–) {

    list->elements[i] = list->elements[i – 1];

    }

    list->elements[index] = element;

    list->size++;

    }

    //6.delete

    void DeleteElement(SequentialList* list, int index) {

    if (index<0 || index>=list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    for (int i = index; i < list->size; i++) {

    list->elements[i] = list->elements[i + 1];

    }

    list->size–;

    }

    //7.find an element

    int FindElement(SequentialList* list, DataType element) {

    for (int i = 0; i < list->size; i++) {

    if (list->elements[i] == element) {

    return i;

    }

    }

    return -1;

    }

    //8.element’s index

    DataType GetElementIndex(SequentialList* list, int index) {

    if (index<0 || index>list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    return list->elements[index];

    }

    //9.modify elements

    void UpdateElement(SequentialList* list, int index, DataType element) {

    if (index<0 || index>list->size) {

    throw std::invalid_argument(“invalid index”);

    }

    list->elements[index] = element;

    }

    int main() {

    SequentialList myList;

    InitializeElement(&myList, 11);

    for (int i = 0; i < 11; i++) {

    InsertElement(&myList, i, i * 10);

    }

    cout << “Size:” << size(&myList)<<endl;

    cout << “Is Empty:” << isEmpty(&myList) << endl;

    for (int i = 0; i < size(&myList); i++) {

    cout << GetElementIndex(&myList, i)<<” “;

    }

    cout << endl;

    DeleteElement(&myList, 2);

    for (int i = 0; i < size(&myList); i++) {

    cout << GetElementIndex(&myList, i) << ” “;

    }

    cout << endl;

    UpdateElement(&myList, 2, 1314);

    for (int i = 0; i < size(&myList); i++) {

    cout << GetElementIndex(&myList, i) << ” “;

    }

    cout << endl;

    int idx = FindElement(&myList, 1314);

    UpdateElement(&myList, idx, 520);

    cout << “Size:” << size(&myList) << endl;

    cout << “Is Empty:” << isEmpty(&myList) << endl;

    for (int i = 0; i < size(&myList); i++) {

    cout << GetElementIndex(&myList, i) << ” “;

    }

    cout << endl;

    DestroyList(&myList);

    return 0;

    }