使用指针计算堆栈问题的大O表示法

时间:2018-10-06 05:38:03

标签: c++ stack big-o

您好,有人可以帮助我使用Big O表示法来计算此代码的算法复杂度吗?我对使用Big O不太了解,因为这段代码中有很多指针。我只知道一些代码。像cout是O(1)。其余的我不明白。我只是编程的初学者。请帮助我数一数。谢谢。

#include <iostream>
#include <string>
#include <stdlib.h>

using namespace std;

class Book {
    int year, page;
    unsigned long long int code;
    string language, name, title;
    Book *head, *next, *prev, *link;

public:
    Book (string & name, string & title, unsigned long long int code, string & language, int year, int page) {
        head = NULL;
        this->name = name;
        this->title = title;
        this->language = language;
        this->code = code;
        this->year = year;
        this->page = page;
    }

    ~Book (void) {
        delete head;
    }

    void display (void);
    void add (void);
    void dellete (void);
};

void Book::add(void) {
    string name, title, language;
    int year, page;
    unsigned long long int code;
    cout << "Add a book...";
    cout << endl << "Author\t\t:", cin >> name;
    cout << "Title\t\t:", cin >> title;
    cout << "ISBN(13 digits)\t:", cin >> code;
    cout << "Language\t:", cin >> language;
    cout << "Year\t\t:", cin >> year;
    cout << "Pages\t\t:", cin >> page;

    Book* p = new Book(name, title, code, language, year, page);
    p->next = head;
    head = p;
}

void Book::dellete(void) {
    string name, title, language;
    int year, page;
    unsigned long long int code;
    Book* p, *prev, *next;

    if(head==NULL) {
        cout << "There is no book in the stack\n";
    } else if(head->next==NULL) {
        p = head;
        head = NULL;
        free(p);
        cout << "All book has been taken. Now the stack is empty\n";
    } else{
        p = head;
        head = p->next;
        free(p);
        cout << "A book has been taken\n";
    }
}

void Book::display(void) {
    Book* p = head;
    cout << "Displaying book(s)...\n";
    while (p) {
        cout << "----------------------------- \n";
        cout << "Author\t\t:" << p->name << endl;
        cout << "Title\t\t:" << p->title << endl;
        cout << "ISBN\t\t:" << p->code << endl;
        cout << "Language\t:" << p->language << endl;
        cout << "Year\t\t:" << p->year << endl;
        cout << "Pages\t\t:" << p->page << endl;
        cout << endl;
        p = p->next;
    }
}

int main (int argc, char const** argv) {
    string blank = "";
    Book* B = new Book(blank, blank, 0, blank, 0, 0);
    int opt;
    for (;;) {
        cout << "----------------------------- \n";
        cout << "1) Add a book.\n";
        cout << "2) Show all books.\n";
        cout << "3) Take a book\n";
        cout << "4) Exit. \n";
        cout << "Don't use space but use underscore...\n\n";

        cout << "Options:", cin >> opt;
        switch (opt) {
            case 1:
                B->add();
                break;
            case 2:
                B->display();
                break;
            case 3:
                B->dellete();
                break;
            case 4:
                exit(0);
            default:
                continue;
        }
    }
    return 0;
}

1 个答案:

答案 0 :(得分:1)

O注释根据问题的大小将算法变得复杂(例如,运行时或内存使用情况)进行分类。因此,O(1)意味着,不管问题有多大,无论此恒定成本有多大,算法的复杂度都不会增加。

让我们查看一些程序部分。

删除

这具有 O(1)的运行时复杂度,因为无论书籍堆栈有多大,它始终与删除书籍顶部的操作量几乎相同堆。唯一的区别是0本书,1本书和2本书之间的区别,但是如果将堆栈扩大到无穷大,操作量就不会增加,这很重要。

添加

在这里很难测量。由于此方法一次只能添加1本书,因此它是 O(1),因为无论已经有多少本书(这是唯一的可变大小),您都需要始终进行相同数量的操作。如果您允许一次添加多本书,那会更有趣。

显示

因此display会打印出堆栈中的所有书籍。如果您增加书籍数量,那么操作数也会增加。现在的问题是什么?在这种情况下,将书籍数量加倍会使说明数量加倍。这是线性增长,因此复杂度类别为 O(n)


查看循环计数可能会有所帮助。问题规模的一个循环通常确实意味着O(n)。如果您有两个嵌套循环(超过问题大小),则通常会有O(n²),依此类推。

对于您的问题,主函数中的无限循环是什么,它取决于您定义的问题大小,我不知道在这里进行测量是否有意义。

如果将用户操作的总数定义为问题大小,则会变得很复杂。如果我们放掉显示部分并只允许添加和删除,则它是O(n),因为所有内容都是常量(因为添加和删除是O(1),其他是独立的指令,例如cout),它们会在基于问题大小n(用户操作的数量)的循环。如果考虑到显示,它并不是那么简单,因为显示具有O(m)复杂度(m =书籍数量),并且高度依赖于之前给出的实际用户输入。我不知道那里的复杂程度。