遍历 AOV 图的所有结点

遍历 AOV 图的所有结点

巨坑,懒得填了。上个学期的数据结构课设,没用到的算法。

//
//  main.cpp
//  教学计划编制系统
//
//  Created by 郭子睿 on 2017/3/6.
//  Copyright © 2017年 郭子睿. All rights reserved.
//

#include "CourseGraph.hpp"


int main(int argc, const char * argv[]) {
    Course A,B,C,D,E,F,G,H,I,J,K,L;
    A.No=1;B.No=2;C.No=3;D.No=4;E.No=5;
    F.No=6;G.No=7;H.No=8;
    I.No=9;J.No=10;
    K.No=11;
    L.No=12;
    A.Credit=2;
    B.Credit=3;
    C.Credit=4;
    D.Credit=3;
    E.Credit=2;
    F.Credit=3;
    G.Credit=4;
    H.Credit=4;
    I.Credit=7;
    J.Credit=5;
    L.Credit=2;

    A.Name="高等数学";
    B.Name="大学物理";
    C.Name="数据库";
    D.Name="C++";
    E.Name="数据结构";
    F.Name="计算机组成原理";
    G.Name="计算机图形学";
    H.Name="大学英语";
    I.Name="计算机体系结构";
    J.Name="操作系统";
    K.Name="Java";
    L.Name="人工智能";




    B.DirectNo.push_back(1);
    C.DirectNo.push_back(1);
    C.DirectNo.push_back(2);
    D.DirectNo.push_back(1);
    E.DirectNo.push_back(3);
    E.DirectNo.push_back(4);
    F.DirectNo.push_back(11);
    G.DirectNo.push_back(3);
    H.DirectNo.push_back(3);
    H.DirectNo.push_back(6);
    J.DirectNo.push_back(9);
    K.DirectNo.push_back(9);
    L.DirectNo.push_back(9);
    L.DirectNo.push_back(10);
    L.DirectNo.push_back(1);
    CourseGraph AI;
    AI.add_course(&A);
    AI.add_course(&B);
    AI.add_course(&C);
    AI.add_course(&D);
    AI.add_course(&E);
    AI.add_course(&F);
    AI.add_course(&G);
    AI.add_course(&H);
    AI.add_course(&I);
    AI.add_course(&J);
    AI.add_course(&K);
    AI.add_course(&L);

    bool FUCK=AI.build_graph();
    if(FUCK){
        AI.build_tree();
        Term T(6,10);
        AI.build_path(T,9);
        AI.arrange_loose();
        cout<<endl<<endl;
        AI.arrange_tight();
    }
    return 0;
}
//
// CourseGraph.hpp
// 教学计划编制系统
//
// Created by 郭子睿 on 2017/3/10.
// Copyright © 2017年 郭子睿. All rights reserved.
//

#ifndef CourseGraph_hpp
#define CourseGraph_hpp

#include <stdio.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <stack>
using namespace std;

//课程———————————————————————————————————————————————————————————————————————————
struct Course{
    int No=0;//课程编号
    string Name="";//课程名字
    int Credit=0;//学分
    vector<int> DirectNo;//直接先修课程编号
    Course* Link=NULL;//用于建立图的链表存储
    Course* LChild=NULL;
    Course* RChild=NULL;
    Course* Parent=NULL;

    Course(){}
    Course(const Course& A){
        Parent=A.Parent;
        No=A.No;
        Name=A.Name;
        Credit=A.Credit;
        for(int i=0;i<A.DirectNo.size();++i)
            DirectNo.push_back(A.DirectNo[i]);
    }
    void operator=(const Course& A){
        No=A.No;
        Name=A.Name;
        Credit=A.Credit;
        for(int i=0;i<A.DirectNo.size();++i)
            DirectNo.push_back(A.DirectNo[i]);
    }
};
//学期———————————————————————————————————————————————————————————————————————————
struct Term{
    int Credit;//每学期学分
    int CurrentTerm;//当前学期
    int M;//当前学期所剩学分
    Term(int Credit_,int SumTerm_){
        Credit=Credit_;
        M=Credit;
        CurrentTerm=SumTerm_;
    }
    Term(const Term& tl){
        Credit=tl.Credit;
        M=Credit;
        CurrentTerm=tl.CurrentTerm;
    }
};
//安排———————————————————————————————————————————————————————————————————————————
class CourseGraph{
    vector<Course*> Courses;//用于存储课程信息;并用于存储有向图
    Course* Tree=NULL;//用于存储有向图
    vector<vector<int>> Arrange;
    ofstream Save;
public:
    CourseGraph(){
        Save.open("/Users/guozirui/Desktop/arrangement.txt");
    }
    ~CourseGraph(){
        Save.close();
        for (int i=0; i<Courses.size(); ++i){//删除 Courses
            Course* temp=Courses[i]->Link;
            while(Courses[i]->Link!=NULL){
                while(temp!=NULL)
                    temp=temp->Link;
                delete temp;
                temp=Courses[i]->Link;
            }
            delete Courses[i];
        }
        destroy(Tree);//删除 Tree
    }
    void add_course(Course* temp);//增加课程

    bool build_graph();//建图
    void build_tree();
    void build_tree_part1(Course* Root);
    void build_tree_part2(Course* Root,stack<Course*>& TEMP_);

    Course* operator[](int i);//按课程编号搜索,返回课程
    int return_no(int i);//按课程编号搜索,返回课程在 Courses 里的位置

    vector<stack<Course>> caculate_path();

    void find_leaf(Course* Root,vector<stack<Course*>>& Way);
    void build_path(const Term& T,int Wanted);
    void show_arrange(vector<int> C,bool X);
    void rank(bool A);//A 为假,升序排列;A 为真,降序排列。

    void arrange_tight();//紧密安排
    void arrange_loose();//均匀安排

    //其他操作——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
    void destroy(Course* Root){
        if(Root==NULL)
            return;
        if(Root->LChild==NULL&&Root->RChild==NULL){
            delete Root;
            Root=NULL;
        }
        else{
            if(Root->LChild!=NULL)
                destroy(Root->LChild);
            if(Root->RChild!=NULL)
                destroy(Root->RChild);
        }
    }
    void swap(vector<int>* a,vector<int>* b){
        vector<int> temp;
        temp=*a;
        *a=*b;
        *b=temp;
    }
};




#endif /* CourseGraph_hpp */
//
// CourseGraph.cpp
// 教学计划编制系统
//
// Created by 郭子睿 on 2017/3/10.
// Copyright © 2017年 郭子睿. All rights reserved.
//

#include "CourseGraph.hpp"

void CourseGraph::rank(bool A){
    if(A){//升序排列;松散安排(因为比较的是剩余学期数,所以剩余学期数越小的安排得越松散)
        for(int i=0;i<Arrange.size();++i){
            for(int j=(int)Arrange.size()-1;j>i;j--){
                if(Arrange[j].back()<Arrange[j-1].back()){
                    swap(&Arrange[j], &Arrange[j-1]);
                }
            }
        }
    }
    else{//降序排列;紧密安排
        for(int i=0;i<Arrange.size();++i){
            for(int j=(int)Arrange.size()-1;j>i;j--){
                if(Arrange[j][Arrange[j].size()-2]>Arrange[j-1][Arrange[j].size()-2]){
                    swap(&Arrange[j], &Arrange[j-1]);
                }
            }
        }
    }
}
void CourseGraph::add_course(Course *temp){
    Courses.push_back(temp);
}
bool CourseGraph::build_graph(){
    for(int i=0;i<Courses.size();++i){//建图
        if(Courses[i]->DirectNo.size()==0)//如果该课程没有先决课程
            continue;//那么继续
        else{//如果该课程有先决课程
            for(int j=0;j<Courses[i]->DirectNo.size();++j){
                Course* temp=new Course(*Courses[i]);
                if(return_no(Courses[i]->DirectNo[j])==-1){
                    cout<<"课程设置错误!";
                    return false;
                }
                Course* temp1=Courses[return_no(Courses[i]->DirectNo[j])];
                while(temp1->Link!=NULL)
                    temp1=temp1->Link;
                temp1->Link=temp;
            }
        }
    }
    Course* temp=NULL;
    for(int i=0;i<Courses.size();++i){
        if(Tree==NULL&&Courses[i]->DirectNo.size()==0){
            Tree=new Course(*Courses[i]);
            temp=Tree;
            continue;
        }
        if(Courses[i]->DirectNo.size()==0){
            while(temp->RChild!=NULL)
                temp=temp->RChild;
            temp->RChild=new Course(*Courses[i]);
        }
    }
    return true;
}
Course* CourseGraph::operator[](int i){
    for(int j=0;j<Courses.size();++j)
        if(Courses[j]->No==i)
            return Courses[j];
    return NULL;
}
int CourseGraph::return_no(int i){
    for(int j=0;j<Courses.size();++j)
        if(Courses[j]->No==i)
            return j;
    return -1;

}
void CourseGraph::build_tree(){
    stack<Course*> TEMP;
    for(int L=0;L<Courses.size();++L){
        build_tree_part2(Tree,TEMP);
        while(!TEMP.empty()){
            build_tree_part1(TEMP.top());
            TEMP.pop();
        }
    }

}
void CourseGraph::build_tree_part1(Course *Root){
    Course* temp=NULL;
    Course* temp1=NULL;
    Course* temp2=NULL;

    if(Root==NULL)
        return;
    bool* Ava=new bool[Courses.size()]{false};//用于保存已经安排的课程个数
    temp=Root->Parent;
    while(temp!=NULL){//用于计算已经选过的课程
        Ava[return_no(temp->No)]=true;//将已经选过的课程置为已选
        temp=temp->Parent;
    }

    if(Root->Parent==NULL){//如果该课程没有父母结点
        temp=Tree;
        while(temp!=NULL){
            if(temp!=Root){
                if(Root->LChild==NULL){
                    Ava[return_no(temp->No)]=true;
                    Root->LChild=new Course(*temp);
                    Root->LChild->Parent=Root;
                    temp2=Root->LChild;
                }
                else{
                    Ava[return_no(temp->No)]=true;
                    temp2->RChild=new Course(*temp);
                    temp2->RChild->Parent=Root;
                    temp2=temp2->RChild;
                }
            }
            temp=temp->RChild;
        }

        temp1=Courses[return_no(Root->No)]->Link;
        if(temp1==NULL)
            return;
        while(temp1!=NULL){
            if(Root->LChild==NULL){
                temp=new Course(*temp1);
                if(Ava[return_no(temp->No)]==false){
                    Ava[return_no(temp->No)]=true;
                    Root->LChild=temp;
                    temp->Parent=Root;
                    temp2=Root->LChild;
                }
            }
            else{
                temp=new Course(*temp1);
                if(Ava[return_no(temp->No)]==false){
                    Ava[return_no(temp->No)]=true;
                    temp2->RChild=temp;
                    temp2=temp2->RChild;
                    temp2->Parent=Root;
                }
            }
            temp1=temp1->Link;
        }
        return;
    }
    else{
        temp1=NULL;
        temp2=NULL;
        temp=Root->Parent->LChild;//让 temp 指针指向第一个孩子
        while(temp==Root)
            temp=temp->RChild;//找到 Root 的父母的第一个不是 Root 的孩子
        if(temp!=NULL){
            temp1=new Course(*temp);//temp1 用于新建结点
            Root->LChild=temp1;
            Ava[return_no(temp1->No)]=true;
            Root->LChild->Parent=Root;
            temp=temp->RChild;
            temp2=Root->LChild;
            while(temp!=NULL){
                if(temp==Root){
                    temp=temp->RChild;
                    continue;
                }
                temp1=new Course(*temp);
                temp2->RChild=temp1;
                temp2->RChild->Parent=Root;
                Ava[return_no(temp1->No)]=true;
                temp=temp->RChild;
                temp2=temp2->RChild;
            }
        }

        temp=Courses[return_no(Root->No)]->Link;
        while (temp!=NULL){
            if(Root->LChild==NULL){
                if(Ava[return_no(temp->No)]!=true){
                    temp1=new Course(*temp);
                    Root->LChild=temp1;
                    Root->LChild->Parent=Root;
                    temp2=Root->LChild;
                }
                temp=temp->Link;
            }
            else{
                if(Ava[return_no(temp->No)]!=true){
                    temp1=new Course(*temp);
                    temp2->RChild=temp1;
                    temp2->RChild->Parent=Root;
                    temp2=temp2->RChild;
                }
                temp=temp->Link;
            }
        }
    }

}
void CourseGraph::build_tree_part2(Course* Root,stack<Course*>& TEMP_){
    if(Root->LChild==NULL)
        TEMP_.push(Root);
    if(Root->LChild!=NULL)
        build_tree_part2(Root->LChild,TEMP_);
    if(Root->RChild!=NULL)
        build_tree_part2(Root->RChild,TEMP_);
    return;
}
void CourseGraph::find_leaf(Course* Root,vector<stack<Course*>>& Way){
    if(Root->LChild==NULL&&Root->RChild==NULL){
        stack<Course*> temp;
        Course* temp1=new Course(*Root);
        temp.push(temp1);
        Way.push_back(temp);
        return;
    }
    else{
        if(Root->LChild!=NULL)
            find_leaf(Root->LChild,Way);
        if(Root->RChild!=NULL)
            find_leaf(Root->RChild,Way);
        return;
    }
}
void CourseGraph::build_path(const Term& T,int Wanted){
    vector<stack<Course*>> Way;
    find_leaf(Tree,Way);
    int Plus;
    if(Wanted>Way.size())
        Plus=1;
    else
        Plus=(int)((float)Way.size()/Wanted+0.5);
    for(int i=0;i<Way.size();i=i+Plus){//求出所有路径
        Course* temp=Way[i].top();
        while(temp->Parent!=NULL){
            Course* temp1=new Course(*temp->Parent);
            Way[i].push(temp1);
            temp=temp->Parent;
        }
    }

    for(int i=0;i<Way.size();i=i+Plus){
        Term TL(T);
        for(int j=0;j<Way[i].size();j++){
            vector<int> C;
            C.push_back(0);
            while(Way[i].size()!=0){
                if(TL.M>=Way[i].top()->Credit){//如果该学期学分还够的话
                    TL.M-=Way[i].top()->Credit;//就减去该课程学分
                    C.push_back(Way[i].top()->No);
                    delete Way[i].top();
                    Way[i].pop();
                }
                else{
                    TL.CurrentTerm--;
                    if(TL.CurrentTerm==0&&Way[i].size()!=0)
                        break;
                    C.push_back(0);
                    TL.M=TL.Credit;
                    TL.M-=Way[i].top()->Credit;
                    C.push_back(Way[i].top()->No);
                    delete Way[i].top();
                    Way[i].pop();
                }
            }
            if(Way[i].size()!=0)
                continue;
            C.push_back(TL.CurrentTerm);
            C.push_back(TL.CurrentTerm);
            Arrange.push_back(C);
        }
    }
    for(int i=0;i<Way.size();++i){
        while(!Way[i].empty()){
            delete Way[i].top();
            Way[i].pop();
        }
        Way.pop_back();
    }
    for(int i=0;i<Arrange.size();++i){
        for(int j=1;j<Arrange[i].size()-2;++j){
            if(Arrange[i].back()<2)
                break;
            if(Arrange[i][j]==0||Arrange[i][j]==-1)
                continue;
            else if(Arrange[i][j-1]!=0&&Arrange[i][j-1]!=-1){
                Arrange[i].insert(Arrange[i].begin()+j,-1);
                Arrange[i].back()--;
            }
        }
    }
}

void CourseGraph::arrange_tight(){
    cout<<"!!!!!!!!!!!!!!!!!!紧密安排!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
    Save<<"!!!!!!!!!!!!!!!!!!紧密安排!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
    for(int i=0;i<Arrange.size();++i){
        cout<<"第"<<i+1<<"种方法";
        Save<<"第"<<i+1<<"种方法";
        show_arrange(Arrange[i],0);
        cout<<endl<<endl;
        Save<<endl<<endl;
    }
}
void CourseGraph::arrange_loose(){
    cout<<"!!!!!!!!!!!!!!!!!!松散安排!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
    Save<<"!!!!!!!!!!!!!!!!!!松散安排!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
    for(int i=0;i<Arrange.size();++i){
        cout<<"第"<<i+1<<"种方法";
        Save<<"第"<<i+1<<"种方法";
        show_arrange(Arrange[i],1);
        cout<<endl<<endl;
        Save<<endl<<endl;
    }
}
void CourseGraph::show_arrange(vector<int> C,bool X){
    if(X){
        int k=1;
        for(int i=0;i<C.size()-2;++i){
            if(C[i]==0||C[i]==-1){
                cout<<endl<<"第"<<k<<"学期"<<endl;
                Save<<endl<<"第"<<k<<"学期"<<endl;
                k++;
            }
            else{
                cout<<"课程编号:"<<Courses[return_no(C[i])]->No<<" "<<"学分:"<<Courses[return_no(C[i])]->Credit<<endl;
                Save<<"课程编号:"<<Courses[return_no(C[i])]->No<<" "<<"学分:"<<Courses[return_no(C[i])]->Credit<<endl;
                cout<<"课程名称:"<<Courses[return_no(C[i])]->Name<<endl;
                Save<<"课程名称:"<<Courses[return_no(C[i])]->Name<<endl;
            }
        }
    }
    else{
        int k=1;
        for(int i=0;i<C.size()-2;++i){
            if(C[i]==0){
                cout<<endl<<"第"<<k<<"学期"<<endl;
                Save<<endl<<"第"<<k<<"学期"<<endl;
                k++;
            }
            else if(C[i]==-1)
                continue;
            else{
                cout<<"课程编号:"<<Courses[return_no(C[i])]->No<<" "<<"学分:"<<Courses[return_no(C[i])]->Credit<<endl;
                Save<<"课程编号:"<<Courses[return_no(C[i])]->No<<" "<<"学分:"<<Courses[return_no(C[i])]->Credit<<endl;
                cout<<"课程名称:"<<Courses[return_no(C[i])]->Name<<endl;
                Save<<"课程名称:"<<Courses[return_no(C[i])]->Name<<endl;
            }
        }
    }
}
    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/star_mountain/article/details/60995696
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞