A university's advising department needed software for planning courses for students. The software needed to be able to add courses which had a name, number, and 0 or more prerequisites. The software would then print the courses in alphanumeric order and attempt to maintain the prerequisite constraint in which prerequisite courses must come before their dependent courses.
The correct data structure can be the difference between a program being usable and being relatively worthless from a user's perspective. This is due to the fact that the number of computations that must be performed can dramatically change depending on the data structure and algorithm used for a task. The sorting, searching, and inserting requirements of the program made the binary search tree a good choice because there were no specific memory constraints.
Inserting courses in a binary search tree such that they maintained the prerequisite constraint and were also sorted in alphanumeric order was an interesting problem. Compared to a simpler definition of larger and smaller, extra insertion logic was needed to find where each element should go. I spent a lot of time using trial and error, working through insertions into small trees on paper, brainstorming and implementing ideas. In the end, I realize the problem needed to be more formally defined, as coming up with a solution to problem which I only understood a loosely defined definition was not an easy task.
How has your work on this project expanded your approach to designing software and developing programs?
Due to the roadblocks that I encountered, I realize thoroughly defining the problem to solve is just as important as coming up with a solution. If the problem itself is not understood and all cases do not have defined behavior, the problem cannot be solved.
How has your work on this project evolved the way you write programs that are maintainable, readable, and adaptable?
In this project, I utilized more C++ features that help make programs safer from common mistakes. I also broke up tasks into smaller functions that each preferably have a single responsibliity, which makes testing and debugging programs much easier. This only becomes more essential as software systems become larger and more complex.