題目:Hire and Fireios
題目翻譯成數據結構就是:建樹,加結點,刪除結點,打印結點。只有刪除結點稍微複雜點,由於刪除設計掉樹的調整。數據結構
首先要考慮樹怎麼存儲才能使解題更順手。spa
1.咱們要存儲每一個結點的孩子,父親和名字。存儲孩子是由於第一個孩子可能會「升級」,存儲父親是由於要打印,名字確定也是要打印的;翻譯
2.咱們要知道每一個結點的子樹,刪除結點會涉及調整;設計
3.咱們要知道根節點,存放CEO。指針
因此咱們的結點出來了,以下:code
struct Tman { string name; Tman *father; list<Tman *> sons; };
思路都在註釋裏。blog
代碼以下:遞歸
#include<iostream> #include<map> #include<list> #include<string> using namespace std; //存儲名字,父親,孩子就行 struct Tman { string name; Tman *father; list<Tman *> sons; }; //key是結點名字,value是名字的子樹 map<string, Tman *> hash; //根結點,指向CEO,打印是要用 Tman *root; void print(long dep, Tman *now) { if(now == NULL) return; for(long i = 1; i <= dep; ++i) cout<<"+"; cout<<now->name<<endl;; //遞歸打印每一個孩子結點 for(list<Tman *>::iterator j = now->sons.begin(); j != now->sons.end(); ++j) print(dep + 1, *j); } void hires(string n1, string n2) { Tman *boss = hash[n1];//父親的子樹指針 Tman *employee = new Tman();//新建一個Tman結構體,用於存儲新加入的結點 employee->name = n2;//新加入結點的名字 employee->father = boss;//n1是n2的父親 boss->sons.push_back(employee);//把n2放入n1的孩子list中 hash[n2] = employee;//新加入的結點也要有子樹 } void fire(string n1) { Tman *p = hash[n1];//指向n1結點的指針 hash.erase(n1); while(p->sons.size() > 0)//若是要刪的結點有孩子 { p->name = p->sons.front()->name;//第一個孩子取代父親的地位 hash[p->name] = p;//父親的子樹交給第一個孩子 p = p->sons.front();//p往下移動,始終指向孩子隊列的第一個 } p->father->sons.remove(p);//最後一個沒有孩子的結點「刪除」,其實是上移了 delete p;//防止野指針 } void solve() { string str1,str2; long i; cin>>str1; root = new Tman(); hash[str1] = root; root->name = str1; while(cin>>str1) { if(str1 == "print") { print(0,root); cout<<"------------------------------------------------------------"<<endl; } else if(str1 == "fire") { cin>>str2; fire(str2); } else { cin>>str2; cin>>str2; hires(str1, str2); } } } int main() { solve(); return 0; }