[Tree]Family

//Created: July 2nd, 2015 Thu
//Last Modified: July 5th, 2015 Sun
//A Non-Linear Data Structure - Tree
//Note: On July 3rd, 2015. Initially I designed this Tree in this way, that only children know their fathers while fathers don't know their children. I designed the tree this way because I think that this is a easy way to avoid a problem that is I don't know the number of children, and it is hard to define this number in node class. Now I found a problem with my way, that is as fathers don't know their children, the root which is grandest father have no idea where his children are as it is not pointing to anything. A way to solve this new problem is using a "static" representation. By using array [] to include all nodes and traverse them to construct the relations of a tree
//Note: On July 3rd, 2015. I decided to design this tree in this way that each node know its "head child" and its "next brother or sister" to solve the problem illustrated above
//Note: On July 5th, 2015. This family tree should have following abilities: add a family member directly to it by giving a name string only. The family tree will new a family member for this new member
//Note: On July 6th, 2015. More need to do with this: 1. method - delete 2. method - output, show the family structure 3. traverse - corner case with the last child
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;

class Date
{
public:
    Date();
    Date(int month_par, int day_par, int year_par);
    Date(Date& date_par);
    Date(int date_par); //EX: 20150703
    Date(string month_par, int day_par, int year_par); //EX: "Jul" 3 2015
    //
    int get_month();
    string get_month_string();
    int get_day();
    int get_year();
    int get_age();
    //
    void input();
    void output();
    void modify(int date_par);
    void modify(int month_par, int day_par, int year_par);
    //void modify(Date& date_par);
private:
    int month;
    int day;
    int year;
};

class FamilyMember
{
public:
    FamilyMember();
    FamilyMember(FamilyMember& family_member_par);
    FamilyMember(string name_par);
    FamilyMember(string name_par, int birthday_par, bool is_male_par, bool is_married_par, bool is_alive_par);
    FamilyMember(string name_par, int birthday_par, FamilyMember& first_child_par, FamilyMember& next_sibling_par);
    //
    string get_name();
    Date get_birthday();
    bool is_male();
    bool is_married();
    bool is_alive();
    FamilyMember* get_first_child();
    FamilyMember* get_next_sibling();
    //
    int children_number();
    int siblings_number();
    int get_age();
    void input();
    void output();
    //
    void modify_first_child(FamilyMember& family_member_par);
    void modify_next_sibling(FamilyMember& family_member_par);
    void modify(FamilyMember& family_member_par);
    void modify(string name_par, int birthday_par, bool is_male_par, bool is_married_par, bool is_alive_par);
private:
    string name;
    Date birthday;
    bool male;
    bool married;
    bool alive;
    FamilyMember *first_child;
    FamilyMember *next_sibling;
};


class StackMember
{
public:
    StackMember();
    StackMember(FamilyMember& family_member_par);
    StackMember(FamilyMember& family_member_par, StackMember& next_par);
    void modify(FamilyMember& family_member_par, StackMember& next_par);
    void modify_member(FamilyMember& family_member_par);
    void modify_next(StackMember& next_par);
    FamilyMember* get_family_member();
    StackMember* get_next();
    void output();
private:
    FamilyMember *p;
    StackMember *next;
};

class Stack
{
public:
    Stack();
    void push(StackMember& stack_member_par);
    void push(FamilyMember& family_member_par);
    void pop();
    void output();
    StackMember* get_top();
    bool empty();
    int get_size();
    void clear();
private:
    StackMember *top;
};

class FamilyTree
{
public:
    FamilyTree();
    FamilyTree(FamilyTree& family_tree_par);
    FamilyTree(FamilyMember& root_par);
    //
    FamilyMember* locate_member(string family_member_par);
    void combine(FamilyTree& family_tree_par);
    void add_member(string family_father_par, FamilyMember& family_member_par);
    void add_member(FamilyMember& family_father_par, FamilyMember& family_member_par);
    void delete_member(string family_member_par);
    void modify_root(FamilyMember& root_par);
    //
    int generations_number();
    int family_members_number();
    bool empty();
    //
    void output();
    //
    FamilyMember* get_root();
private:
    FamilyMember *root;
    Stack stack;

};

//------------------------------------------Global Variable------------------------------
Date today;
//------------------------------------------Global variable------------------------------

//------------------------------------------Main-----------------------------------------

int main()
{
    today.modify(7, 5, 2015);
    cout << "Today: ";
    today.output();
    cout << endl;

    FamilyMember *M = new FamilyMember[30];
    M[0].modify("Mayer Amschel Rothschild", 17440223, true, true, false);

    M[1].modify("Amschel Mayer Rothschild", 17730612, true, true, false);
    M[2].modify("Salomon Mayer von Rothschild", 17740909, true, true, false);
    M[3].modify("Nathan Mayer, Freiherr von Rothschild", 17770916, true, true, false);
    M[4].modify("Carl Mayer von Rothschild", 17880424, true, true, false);
    M[5].modify("James Mayer de Rothschild", 17920515, true, true, false);
    /*
    M1->output();
    M2->output();
    M3->output();
    M4->output();
    M5->output();
    M0.output();
    */

    /*
    M0.modify_first_child(*M1);
    M1->modify_next_sibling(*M2);
    M2->modify_next_sibling(*M3);
    M3->modify_next_sibling(*M4);
    M4->modify_next_sibling(*M5);
    M5->modify_next_sibling(*M1);

    M5->output();
    M4->output();
    M3->output();
    M2->output();
    M1->output();
    M0.output();
    */  

    cout << "---------------Begin Constructing Family Tree:---------------\n";

    FamilyTree *family_tree_rothschild = new FamilyTree;
    family_tree_rothschild->modify_root(M[0]);
    family_tree_rothschild->add_member(M[0], M[1]);

    family_tree_rothschild->add_member(M[0], M[2]);
    //(family_tree_rothschild->get_root())->output();
    family_tree_rothschild->add_member(M[0], M[3]);
    //(family_tree_rothschild->get_root())->output();
    family_tree_rothschild->add_member(M[0], M[4]);
    //(family_tree_rothschild->get_root())->output();
    family_tree_rothschild->add_member(M[0], M[5]);
    //(family_tree_rothschild->get_root())->output();
    M[6].modify("Anselm Salonmon von Rothschild", 18030129, true, true, false);
    M[7].modify("Betty Salonmon von Rothschild", 18050000, false, true, false);
    family_tree_rothschild->add_member("Salomon Mayer von Rothschild", M[6]);
    family_tree_rothschild->add_member("Salomon Mayer von Rothschild", M[7]);
    M[8].modify("Mathilde Hannah von Rothschild", 18320305, false, true, false);
    M[9].modify("Nathaniel Meyer von Rothschild", 18361026, true, true, false);
    M[10].modify("Ferdinand de Rothschild", 18391217, true, true, false);
    M[11].modify("Albert Salomon von Rothschild", 18441029, true, true, false);
    M[12].modify("Alice Charlotte von Rothschild", 18470217, false, true, false);
    for(int i=8; i<13; i++)
    {
        family_tree_rothschild->add_member("Anselm Salonmon von Rothschild", M[i]);
    }
    if( M[12].get_next_sibling() == NULL )
    {
        cout << "What?\n";
    }
    else
    {
        cout << M[12].get_name() << "'s Next Sibling is " << ( M[12].get_next_sibling() )->get_name() << endl;
    }
    M[13].modify("Lionel Nathan de Rothschild", 18081122, true, true, false);
    M[14].modify("Anthony Nathan de Rothschild", 18100529, true, true, false);
    M[15].modify("Nathaniel de Rothschild", 18120702, true, true, false);
    M[16].modify("Mayer Amschel de Rothschild", 18180629, true, true, false);
    for(int i=13; i<17; i++)
    {
        cout << "Begin Adding Children of Natahn....\n";
        family_tree_rothschild->add_member("Nathan Mayer, Freiherr von Rothschild", M[i]);
    }
    M[17].modify("Loius Nathaniel de Rothschild", 18820305, true, true, false);
    family_tree_rothschild->add_member("Albert Salomon von Rothschild", M[17]);

    family_tree_rothschild->output();

    M[18].modify("Carl Mayer von Rothschild", 17920515, true, true, false);
    M[19].modify("Charlotte von Rothschild", 18190613, false, true, false);
    M[20].modify("Mayer Carl von Rothschild", 18200805, true, true, false);
    M[21].modify("Wilhelm Carl von Rothschild", 18280516, true, true, false);
    //M[19].modify("Charlotte de Rothschild", 18250506, false, true, false);
    //M[20].modify("Alphonse James de Rothschild", 18270201, true, true, false);
    //M[21].modify("Gustave de Rothschild", 18290217, true, true, false);
    //M[22].modify("Salomom James de Rothschild", 18350330, true, true, false);
    //M[23].modify("Edmond James de Rothschild", 18450819, true, true, false);

    FamilyTree *family_tree_carl = new FamilyTree(M[18]);
    family_tree_carl->add_member("Carl Mayer von Rothschild", M[19]);
    family_tree_carl->add_member("Carl Mayer von Rothschild", M[20]);
    family_tree_carl->add_member("Carl Mayer von Rothschild", M[21]);

    family_tree_carl->output();
    family_tree_rothschild->combine(*family_tree_carl);
    M[5].output();
    family_tree_carl->output();
    family_tree_rothschild->output();



    delete family_tree_rothschild;
    family_tree_rothschild = NULL;
    delete [] M;
    M = NULL;
    return 0;
}
//------------------------------------------Main-----------------------------------------

//------------------------------------------Date-----------------------------------------
Date::Date()
{
    month = 0;
    day = 0;
    year = 0;
}

Date::Date(int month_par, int day_par, int year_par)
{
    month = month_par;
    day = day_par;
    year = year_par;
}

Date::Date(Date& date_par)
{
    month = date_par.get_month();
    day = date_par.get_day();
    year = date_par.get_year();
}

Date::Date(int date_par)
{
    int date = date_par;
    day = date%100;
    month = (date/100)%100;
    year = date/10000;
}

Date::Date(string month_par, int day_par, int year_par)
{
    month = 0;
    if(month_par == "Jan") month = 1; 
    if(month_par == "Feb") month = 2; 
    if(month_par == "Mar") month = 3; 
    if(month_par == "Apr") month = 4; 
    if(month_par == "May") month = 5; 
    if(month_par == "Jun") month = 6; 
    if(month_par == "Jul") month = 7; 
    if(month_par == "Aug") month = 8; 
    if(month_par == "Sep") month = 9; 
    if(month_par == "Oct") month = 10;
    if(month_par == "Nov") month = 11; 
    if(month_par == "Dec") month = 12; 
    day = day_par;
    year = year_par;
}

int Date::get_month()
{
    return month;
}

string Date::get_month_string()
{
    switch(month)
    {
        case 1: return "Jan"; break;
        case 2: return "Feb"; break;
        case 3: return "Mar"; break;
        case 4: return "Apr"; break;
        case 5: return "May"; break;
        case 6: return "Jun"; break;
        case 7: return "Jul"; break;
        case 8: return "Aug"; break;
        case 9: return "Sep"; break;
        case 10: return "Oct"; break;
        case 11: return "Nov"; break;
        case 12: return "Dec"; break;
        default: return "NONE"; break;
    }
}

int Date::get_day()
{
    return day;
}

int Date::get_year()
{
    return year;
}

int Date::get_age()
{
    int age(0);
    if(today.get_month() >= month && today.get_day() >= day)
    {
        age ++;
    }
    age = age + today.get_year() - year - 1;
    if(age < 0)
    {
        age = 0;
    }
    return age;
}

void Date::input()
{
    cout << "Please enter the date\n";
    cout << "Month:\t";
    cin >> month;
    cout << "Day:\t";
    cin >> day;
    cout << "Year:\t";
    cin >> year;
    return;
}

void Date::output()
{
    cout << get_month_string() << " " << day << ", " << year; 
    return;
}


void Date::modify(int date_par)
{
    int date = date_par;
    day = date%100;
    month = (date/100)%100;
    year = date/10000;
    return;
}

/*
void Date::modify(Date date_par)
{
    day = date_par.get_day();
    month = date_par.get_month();
    year = date_par.get_year();
    return;
}
*/

void Date::modify(int month_par, int day_par, int year_par)
{
    month = month_par;
    day = day_par;
    year = year_par;
    return;
}

//------------------------------------------Date-----------------------------------------

//------------------------------------------FamilyMember---------------------------------
FamilyMember::FamilyMember()
{
    name = "NONE";  
    birthday.modify(00000000);
    male = false;
    married = false;
    alive = false;  
    first_child = NULL;
    next_sibling = NULL;
}

FamilyMember::FamilyMember(FamilyMember& family_member_par)
{
    name = family_member_par.get_name();
    male = family_member_par.is_male();
    married = family_member_par.is_married();
    alive = family_member_par.is_alive();
    birthday.modify((family_member_par.get_birthday()).get_month(), (family_member_par.get_birthday()).get_day(), (family_member_par.get_birthday()).get_year());
    first_child = family_member_par.get_first_child();
    next_sibling = family_member_par.get_next_sibling();
}

FamilyMember::FamilyMember(string name_par)
{
    name = name_par;
    male = false;
    married = false;
    alive = false;
    birthday.modify(00000000);
    first_child = NULL;
    next_sibling = NULL;
}

FamilyMember::FamilyMember(string name_par, int birthday_par, bool is_male_par, bool is_married_par, bool is_alive_par)
{
    name = name_par;
    male = is_male_par;
    married = is_married_par;
    alive = is_alive_par;
    birthday.modify(birthday_par);
    first_child = NULL;
    next_sibling = NULL;
}

FamilyMember::FamilyMember(string name_par, int birthday_par, FamilyMember& first_child_par, FamilyMember& next_sibling_par)
{
    name = name_par;
    male = false;
    married = false;
    alive = false;
    birthday.modify(birthday_par);
    first_child = &first_child_par;
    next_sibling = &next_sibling_par;
}

string FamilyMember::get_name()
{
    return name;
}

Date FamilyMember::get_birthday()
{
    return birthday;
}

FamilyMember* FamilyMember::get_first_child()
{
    return first_child;
}

FamilyMember* FamilyMember::get_next_sibling()
{
    return next_sibling;
}

int FamilyMember::children_number()
{
    int number(0);
    FamilyMember *p;
    p = first_child;
    if(p!=NULL)
    {
        number ++;
        number = number + p->siblings_number();
    }
    return number;
}

int FamilyMember::siblings_number()
{
    int number(0);
    FamilyMember *p;
    p = next_sibling;
    if(p!=NULL)
    {
        number ++;
        p = p->get_next_sibling();
        while( p->get_name() != name )
        {
            number ++;
            p = p->get_next_sibling();
        }
    }

    return number;
}

void FamilyMember::input()
{
    char is_male('N'), is_married('N'), is_alive('N'), choice('N');
    cout << name << endl;
    cout << "Would you like to change the name of this family member? (Y/N): ";
    cin >> choice;
    if(choice == 'Y' || choice == 'y')
    {
        cout << "Please enter the name:\t"; 
        getline(cin, name);
    }
    choice = 'N';
    cout << "Would you like to change the birthday of this family member? (Y/N): ";
    cin >> choice;
    if(choice == 'Y' || choice == 'y')
    {
        cout << "Please enter the birthday:\t"; 
        birthday.input();
    }
    choice = 'N';
    cout << "Is this family member a male?:(Y/N)\t";
    cin >> is_male;
    if(is_male == 'Y' || is_male == 'y') 
    {
        male = true;
    }
    else
    {
        male = false;
    }
    cout << "Is this family member married?:(Y/N)\t";
    cin >> is_married;
    if(is_male == 'Y' || is_male == 'y') 
    {
        married = true;
    }
    else
    {
        married = false;
    }
    cout << "Is this family member alive?:(Y/N)\t";
    cin >> is_alive;
    if(is_alive == 'Y' || is_alive == 'y') 
    {
        alive = true;
    }
    else
    {
        alive = false;
    }

    return;
}

bool FamilyMember::is_male()
{
    return male;
}

bool FamilyMember::is_married()
{
    return married;
}

bool FamilyMember::is_alive()
{
    return alive;
}

int FamilyMember::get_age()
{
    return birthday.get_age();
}

void FamilyMember::output()
{
    cout << "------------------------------------------------------------\n";
    cout << name << "\n";
    //name

    cout << "Birthday: ";
    birthday.output();
    cout << endl;
    //birthday
    if(alive)
    {
        cout << get_age() << " yeas old\n";
    }
    //age
    if(male)
    {
        cout << "male\t";
    } 
    else
    {
        cout << "female\t";
    }
    //sex 
    if(married)
    {
        cout << "married\n";
    }
    else
    {
        cout << "not married\n";
    }
    //married
    cout << siblings_number() << " siblings\n";
    cout << children_number() << " children\n";
    cout << "------------------------------------------------------------\n";
    return;
}

void FamilyMember::modify_first_child(FamilyMember& family_member_par)
{
    first_child = &family_member_par;
    return;
}

void FamilyMember::modify_next_sibling(FamilyMember& family_member_par)
{
    next_sibling = &family_member_par;
    return;
}

void FamilyMember::modify(FamilyMember& family_member_par)
{
    name = family_member_par.get_name();
    male = family_member_par.is_male();
    married = family_member_par.is_married();
    alive = family_member_par.is_alive();
    birthday.modify( (family_member_par.get_birthday()).get_month(), (family_member_par.get_birthday()).get_day(), (family_member_par.get_birthday()).get_year());
    first_child = family_member_par.get_first_child();
    //sibling not changed
    return;
}

void FamilyMember::modify(string name_par, int birthday_par, bool is_male_par, bool is_married_par, bool is_alive_par)
{
    name = name_par;
    male = is_male_par;
    married = is_married_par;
    alive = is_alive_par;
    birthday.modify(birthday_par);
    first_child = NULL;
    next_sibling = NULL;
    return;
}

//------------------------------------------FamilyMember---------------------------------

//------------------------------------------FamilyTree-----------------------------------
FamilyTree::FamilyTree()
{
    root = NULL;
}

FamilyTree::FamilyTree(FamilyTree& family_tree_par)
{
    root = family_tree_par.get_root();
}

FamilyTree::FamilyTree(FamilyMember& root_par)
{
    root = &root_par;
}

void FamilyTree::modify_root(FamilyMember& root_par)
{
    root = &root_par;
    return;
}

void FamilyTree::combine(FamilyTree& family_tree_par)
{
    FamilyMember *p;
    p = locate_member( (family_tree_par.get_root())->get_name() );
    p->modify( *(family_tree_par.get_root()) );
    return;
}

FamilyMember* FamilyTree::locate_member(string family_member_par)
{
    FamilyMember *p;
    p = root;
    stack.clear();
    while( ( p==NULL && stack.empty() ) == false )
    {
        cout << "This is family member " << p->get_name() << " under checking....\n";
        if(p->get_name() == family_member_par)
        {
            //cout << "Family Member Location Found\n";
            break;
        }
        bool has_sibling(false);
        if(stack.empty())
        {
            if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
            {
                cout << p->get_name() << " has sibling and stack is empty now\n";
                has_sibling = true;
            }
        }
        else
        {
            if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
            {
                cout << p->get_name() << " has sibling and stack is NOT empty now\n";
                has_sibling = true;
            }
        }

        if(p->get_first_child() != NULL)    //has child
        {
            cout << "Location: Member Under Checking has child\n";
            if(p != root)
            {
                stack.push(*p);
            }
            p = p->get_first_child();           
        }
        else if(has_sibling)    //has sibling
        {
            cout << "Location: Member Under Checking has no child, but has sibling\n";
            p = p->get_next_sibling();
        }
        else                                //no child, no sibling, try to go backwards/upwards
        {
            cout << "Location: Member Under Checking has no child, no sibling\n";
            if(stack.empty())
            {
                cout << "Family Member Not in Tree\n";
                break;
            }

            p = ( stack.get_top() ) -> get_family_member();
            cout << "Location: Now the member is: " << p->get_name() << endl;
            stack.pop();

            bool has_sibling_backward(false);
            if(stack.empty())
            {
                if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
                {
                    has_sibling_backward = true;
                }
            }
            else
            {
                if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
                {
                    has_sibling_backward = true;
                }
            }
            if(has_sibling_backward)
            {
                cout << p->get_name() << " has sibling\n";
            }
            while(has_sibling_backward == false)
            {
                p = ( stack.get_top() ) -> get_family_member();
                stack.pop();

                has_sibling_backward = false;
                if(stack.empty())
                {
                    if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
                    {
                        has_sibling_backward = true;
                    }
                }
                else
                {
                    if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
                    {
                        has_sibling_backward = true;
                    }
                }
            }
            p = p->get_next_sibling();
        }
    }
    cout << "Location Finished\n";
    return p;
}

int FamilyTree::generations_number()
{
    //the idea is to traverse the tree, look every elements; then the number of generations would be the largest size of stack + 2;
    int number(0);
    FamilyMember *p;
    p = root;
    if(p==NULL)
    {
        return 0;
    }
    else if(p->get_first_child() == NULL)
    {
        return 1;
    }
    else
    {
        number = 2;
    }
    stack.clear();
    while( ( p==NULL && stack.empty() ) == false )
    {
        if( number < (stack.get_size()+2) )
        {
            number = stack.get_size() + 2;
        }
        bool has_sibling(false);
        if(stack.empty())
        {
            if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
            {
                has_sibling = true;
            }
        }
        else
        {
            if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
            {
                has_sibling = true;
            }
        }


        if(p->get_first_child() != NULL)    //has child
        {
            if(p != root)
            {
                stack.push(*p);
            }
            p = p->get_first_child();           
        }
        else if(has_sibling)    //has sibling -- next_sibling is not NULL and is not the first child
        {
            p = p->get_next_sibling();
        }
        else                                //no child, no sibling, try to go backwards/upwards
        {
            if(stack.empty())
            {
                break;
            }
            p = ( stack.get_top() ) -> get_family_member();
            stack.pop();
            bool has_sibling_backward(false);
            if(stack.empty())
            {
                if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
                {
                    has_sibling_backward = true;
                }
            }
            else
            {
                if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
                {
                    has_sibling_backward = true;
                }
            }

            while(has_sibling_backward == false)
            {
                p = ( stack.get_top() ) -> get_family_member();
                stack.pop();
                has_sibling_backward = false;
                if(stack.empty())
                {
                    if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
                    {
                        has_sibling_backward = true;
                    }
                }
                else
                {
                    if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
                    {
                        has_sibling_backward = true;
                    }
                }
            }
            p = p->get_next_sibling();
        }
    }
    return number;
}

int FamilyTree::family_members_number()
{
    int number(0);
    FamilyMember *p;
    p = root;
    stack.clear();
    while( ( p==NULL && stack.empty() ) == false )
    {
        number ++;

        bool has_sibling(false);
        if(stack.empty())
        {
            if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
            {
                has_sibling = true;
            }
        }
        else
        {
            if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
            {
                has_sibling = true;
            }
        }

        if(p->get_first_child() != NULL)    //has child
        {
            if(p != root)
            {
                stack.push(*p);
            }
            p = p->get_first_child();           
        }
        else if(has_sibling)    //has sibling
        {
            p = p->get_next_sibling();
        }
        else                                //no child, no sibling, try to go backwards/upwards
        {
            if(stack.empty())
            {
                break;
            }

            p = ( stack.get_top() ) -> get_family_member();
            stack.pop();

            bool has_sibling_backward(false);
            if(stack.empty())
            {
                if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
                {
                    has_sibling_backward = true;
                }
            }
            else
            {
                if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
                {
                    has_sibling_backward = true;
                }
            }

            while(has_sibling_backward == false)
            {
                p = ( stack.get_top() ) -> get_family_member();
                stack.pop();

                has_sibling_backward = false;
                if(stack.empty())
                {
                    if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
                    {
                        has_sibling_backward = true;
                    }
                }
                else
                {
                    if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
                    {
                        has_sibling_backward = true;
                    }
                }
            }
            p = p->get_next_sibling();
        }
    }
    return number;
}

void FamilyTree::add_member(string family_father_par, FamilyMember& family_member_par)
{
    FamilyMember *p;
    p = locate_member(family_father_par);
    if( p->is_male() == false)
    {
        cout << "Female Member's children can't be added to family tree\n";
        return;
    }
    if(p->get_first_child() == NULL)    //no child
    {
        p->modify_first_child(family_member_par);
        cout << family_member_par.get_name() << " Added....\nas the first child of " << family_father_par << endl;
    }
    else                                //has at least one child
    {
        p = p->get_first_child();
        family_member_par.modify_next_sibling(*p);
        while( p->get_next_sibling() != family_member_par.get_next_sibling() && p->get_next_sibling() != NULL)
        {
            p = p->get_next_sibling();
        }
        p->modify_next_sibling(family_member_par);
        cout << family_member_par.get_name() << " Added....\nas a sibling of " << p->get_name() << endl;
    }
    return;
}

void FamilyTree::add_member(FamilyMember& family_father_par, FamilyMember& family_member_par)
{
    FamilyMember *p;
    p = locate_member(family_father_par.get_name());
    if( p->is_male() == false)
    {
        cout << "Female Member's children can't be added to family tree\n";
        return;
    }

    if(p->get_first_child() == NULL)
    {
        p->modify_first_child(family_member_par);
        cout << family_member_par.get_name() << " Added....\nas the first child of " << family_father_par.get_name() << endl;
    }
    else
    {
        p = p->get_first_child();
        family_member_par.modify_next_sibling(*p);
        while( p->get_next_sibling() != family_member_par.get_next_sibling() && p->get_next_sibling() != NULL )
        {
            p = p->get_next_sibling();
        }
        p->modify_next_sibling(family_member_par);
        cout << family_member_par.get_name() << " Added....\nas a sibling of " << p->get_name() << endl;        
    }
    return;
}

void FamilyTree::delete_member(string family_member_par)
{
    FamilyMember *p;
    p = locate_member(family_member_par);
    if( p->get_next_sibling() != NULL )
    {
        //++++
    }
    else
    {
        //++++
    }

    return;
}

bool FamilyTree::empty()
{
    return root==NULL;
}

void FamilyTree::output()
{
    if(root == NULL)
    {
        cout << "Empty Tree\n";
        return;
    }
    cout << "---------------Family " << root->get_name() << "---------------\n";
    cout << "------------------------------------------------------------\n";
    cout << "This family has generations of " << generations_number() << endl;
    cout << "This family has family members of " << family_members_number() << endl;
    FamilyMember *p;
    p = root;
    stack.clear();
    while( ( p==NULL && stack.empty() ) == false )
    {
        p->output();

        bool has_sibling(false);
        if(stack.empty())
        {
            if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
            {
                has_sibling = true;
            }
        }
        else
        {
            if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
            {
                has_sibling = true;
            }
        }


        if(p->get_first_child() != NULL)    //has child
        {
            if(p != root)
            {
                stack.push(*p);
            }
            p = p->get_first_child();           
        }
        else if(has_sibling)    //has sibling
        {
            p = p->get_next_sibling();
        }
        else                                //no child, no sibling, try to go backwards/upwards
        {
            if(stack.empty())
            {
                break;
            }

            p = ( stack.get_top() ) -> get_family_member();
            stack.pop();

            bool has_sibling_backward(false);
            if(stack.empty())
            {
                if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
                {
                    has_sibling_backward = true;
                }
            }
            else
            {
                if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
                {
                    has_sibling_backward = true;
                }
            }

            while(has_sibling_backward == false)
            {
                p = ( stack.get_top() ) -> get_family_member();
                stack.pop();

                has_sibling_backward = false;
                if(stack.empty())
                {
                    if( p->get_next_sibling() != NULL && p->get_next_sibling() != root->get_first_child() )
                    {
                        has_sibling_backward = true;
                    }
                }
                else
                {
                    if( p->get_next_sibling() != NULL && p->get_next_sibling() != ( ( stack.get_top() )->get_family_member() )->get_first_child() )
                    {
                        has_sibling_backward = true;
                    }
                }
            }
            p = p->get_next_sibling();
        }
    }



    return;
}

FamilyMember* FamilyTree::get_root()
{
    return root;
}

//------------------------------------------FamilyTree-----------------------------------

//------------------------------------------StackMember----------------------------------
StackMember::StackMember()
{
    p = NULL;
    next = NULL;
}

StackMember::StackMember(FamilyMember& family_member_par)
{
    p = &family_member_par;
    next = NULL;
}

StackMember::StackMember(FamilyMember& family_member_par, StackMember& next_par)
{
    p = &family_member_par;
    next = &next_par;
}

void StackMember::modify(FamilyMember& family_member_par, StackMember& next_par)
{
    p = &family_member_par;
    next = &next_par;
}

void StackMember::modify_member(FamilyMember& family_member_par)
{
    p = &family_member_par;
}

void StackMember::modify_next(StackMember& next_par)
{
    next = &next_par;
}

FamilyMember* StackMember::get_family_member()
{
    return p;
}

StackMember* StackMember::get_next()
{
    return next;
}

void StackMember::output()
{
    cout << "This stack member is:\n";
    if(p!=NULL)
    {
        p->output();
    }
    else
    {
        cout << "NULL";
    }
    return;
}

//------------------------------------------StackMember----------------------------------

//------------------------------------------Stack----------------------------------------

Stack::Stack()
{
    top = NULL;
}

void Stack::push(StackMember& stack_member_par)
{
    StackMember *tmp;
    tmp = top;
    top = &stack_member_par;
    stack_member_par.modify_next(*tmp);
    return;
}

void Stack::push(FamilyMember& family_member_par)
{
    StackMember *s = new StackMember(family_member_par);
    push(*s);
    return;
}

void Stack::pop()
{
    StackMember *tmp;
    tmp = top;
    if(top == NULL)
    {
        cout << "Empty Stack....Nothing to pop\n";
        return;
    }
    top = top->get_next();
    delete tmp;
    return;
}

void Stack::output()
{
    StackMember *n;
    n = top;
    while(n!=NULL)
    {
        n->output();
        n = n->get_next();
    }
    return;
}

StackMember* Stack::get_top()
{
    return top;
}

bool Stack::empty()
{
    return top==NULL;
}

int Stack::get_size()
{
    StackMember *n;
    int number(0);
    n = top;
    while(n != NULL)
    {
        number ++;
        n = n->get_next();
    }
    return number;
}

void Stack::clear()
{
    while( empty() == false )
    {
        pop();      
    }
    return;
}
//------------------------------------------Stack----------------------------------------
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值