「第二章」学习小结

1803 吴兆邦 20181002920

       刚开始接触数据结构这门课程,我明显感觉到这门课程相比于大一的专业课难度提升了很多,

尤其是对算法的理解与灵活运用,以及对C++编程基础等方面有较高的要求。

       第二章我们学习了数据结构课程中最重要的基础——线性表,学习了线性表的处理、编辑方

法,并通过各个例题的学习中了解了线性表中顺序表、链表的不同特点,明确了它们各自的优缺

点,同时让我们学习到要对一个程序进行时间与空间复杂度的分析,实现程序的简便性与高效性。

      在做pta上的例题第2章实践时,我对一个程序是否高效有了较深的体会。

      该题要求我们对给定两个整数集合(每个集合中没有重复元素,集合元素个数<=100000)求

交集,并且非降序输出(即升序)。

       在刚开始写程序时,我仍停留在之前学习C++基础的时候,简单的输入两个数组,然后建立

for循环将两个数组中的元素依次比较,再将相同的数记入新的一个数组,最后进行排序输出。

void rank_fun(int a[], int b[], int m, int n)//建立排序函数
{
    int k = 0, c = 0;
    int w[100000];
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)else if (a[i] == b[j]) {
                w[k] = a[i];
                c = j;
                k++;
                break;
            }
    cout << k << endl;
sort (w ,w + k);
for (int i = 0; i < k; i++) { cout << w[i]; if (i != k - 1) cout << " "; } }

主函数中也未对数组进行处理(摘取部分)

for (int i = 0; i < m; i++) cin >> x[i];
for (int j = 0; j < n; j++) cin >> y[j];
rank_fun(x, y, m, n);

在PTA上运行程序后,发现其测试100000个数的时候超时。意思就是,我写的程序效率太低了。

      此时我才有意地去注意程序的效率,发现在排序函数中,要将毫无顺序的两个函数一个个进行比较,那么

这个程序的时间复杂度将会非常高,无法体现程序的高效性。于是我思考了一会,对主函数与排序函数进行了

一些修改。

首先在主函数中先将两个函数进行升序排序:

    for (int i = 0; i < m; i++) cin >> x[i];
    for (int j = 0; j < n; j++) cin >> y[j];
    sort(x, x + m);
    sort(y, y + n);
    rank_fun(x, y, m, n);

再对排序函数进行优化:(改动思路:当a数组的第i个元素与b数组第j个元素匹配时,用中间变量c记录下j的

值,由于数组已经进行过排序,则可以直接跳出本次for循环,并在第i+1个元素进行比较时,直接与b数组第

c个元素开始比较即可。)

void rank_fun(int a[], int b[], int m, int n)
{
    int k = 0, c = 0;
    int w[100000];
    for (int i = 0; i < m; i++)
        for (int j = c; j < n; j++) //从第c项开始比较
             if (a[i] == b[j]) {
                w[k] = a[i];
                c = j;
                k++;
                break;
            }
    cout << k << endl;
    for (int i = 0; i < k; i++) {
        cout << w[i];
        if (i != k - 1) cout << " ";
    }

}

处理完函数以后,虽然程序效率得到了显著提升,但是仍然未通过验证,原因依旧是运行超时。也就是还要对

程序进行进一步优化。此时我再次注意到,当a数组第i个元素与b数组第j个元素匹配后,a数组第i+1个元素将

会直接与b数组的第j+1个元素进行比较,但如果第i+1个元素比b数组第j+1个元素小,不会直接进入第i+2个元

素与第j+1个元素比较,而会继续进行无意义的for循环。所以我对排序函数继续进行优化:

void rank_fun(int a[], int b[], int m, int n)
{
    int k = 0, c = 0;
    int w[100000];
    for (int i = 0; i < m; i++)
        for (int j = c; j < n; j++)
            if(b[j]>a[i]) break; //若a[i]比b[j]小,直接跳过比较
            else if (a[i] == b[j]) {
                w[k] = a[i];
                c = j;
                k++;
                break;
            }
    cout << k << endl;
    for (int i = 0; i < k; i++) {
        cout << w[i];
        if (i != k - 1) cout << " ";
    }
}

修改过后,终于通过了验证。

       通过本题的练习,让我对程序的高效性有了进一步的了解,督促我在之后的编程中

时刻注意程序的效率,避免将程序运行复杂化。

 

posted on 2019-03-17 22:36  きりぎりさん  阅读(203)  评论(1)    收藏  举报

导航