主頁 > 軟體設計 > 二叉樹家譜關系實驗報告

二叉樹家譜關系實驗報告

2020-12-07 10:45:10 軟體設計

用二叉樹表示家譜關系并實作各種查找功能

撰寫一個程式exp7-9.cpp,采用一棵二叉樹表示一個家譜關系(由若干家譜記錄構成,每個家譜記錄由父親、母親和兒子的姓名構成,其中姓名是關鍵字),要求程式具有以下功能,
(1)檔案操作功能:家譜記錄的輸入,家譜記錄的輸出,清除全部檔案記錄和將家譜記錄存盤,要求在輸入家譜記錄時按從祖先到子孫的順序輸入,第一個家譜記錄的父親域為所有人的祖先,
(2)家譜操作功能:用括號表示法輸出家譜二叉樹,查找某人的所有兒子,查找某人的所有祖先(這里的祖先是指所設計的二叉樹結構中某結點的所有祖先結點),

在這里插入圖片描述
我的樹是這樣的(借鑒別人的)
在這里插入圖片描述
檔案里存的樹是這樣的

在這里插入圖片描述
存家庭要存三個人,

在這里插入圖片描述
在這里插入圖片描述
保存到檔案在這里插入圖片描述

我的代碼是這樣的

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
string s[100];//讀檔案存節點
int i = 0;//讀檔案時記錄節點個數
bool flag = false;//洗掉清空后用來確定 創建ancestor   
struct TreeNode{
    string name;
    struct TreeNode *lChild;
    struct TreeNode *rChild;
};

//檔案操作:
//家譜記錄的輸入(要求在輸入家譜記錄時按從祖先到子孫的順序輸入,
//第一個家譜記錄的父親域為所有人的祖先,)   
//輸入存父母孩子
TreeNode *savePerson(){
    cout<<"輸入父母孩子名字,以空格分開:";
    string s1,s2,s3;
    cin>>s1>>s2>>s3;
    TreeNode *father = new TreeNode;
    father->lChild = father->rChild = NULL;
    father->name = s1;
    TreeNode *mother = new TreeNode;
    mother->lChild = mother->rChild = NULL;
    mother->name = s2;
    TreeNode *son = new TreeNode;
    son->lChild = son->rChild = NULL;
    son->name = s3;
    father->lChild = mother;
    mother->rChild = son;
    return father;
}//女只用右孩子,男左邊妻子,右邊兒子

//遍歷查找人名 
TreeNode* Find(TreeNode *node,string name){
    if(node==NULL)return NULL;
    if(node->name==name)return node;
    TreeNode *temp = Find(node->lChild,name);
    if(temp!=NULL)return temp;
    temp = Find(node->rChild,name);
    if(temp!=NULL)return temp;
    return NULL;
}

//存小孩父母 如果同一父母
void save(TreeNode *root){
    //這是家譜中已有祖先的情況
    TreeNode *fam = savePerson();//父是根節點
    TreeNode *result = Find(root,fam->name);
    if(result!=NULL){
        if(result->lChild==NULL){
            //沒老婆兒子 result是在家譜找到的父節點
            result->lChild = fam->lChild;
        }else{
            //有妻子兒子
            TreeNode *temp = result->lChild;//指向父老婆(母)
            while(temp->rChild!=NULL){
            temp = temp->rChild;
            }
            temp->rChild = fam->lChild->rChild; //fam中的孩子
        }
    }else if(result==NULL){
        cout<<"沒有找到你的祖先,不存入"<<endl;
    }
}
//-------------------------------------------------------------------------------------

//家譜記錄的輸出
void showFamily(TreeNode *node){

    if(node==NULL)return;
    if(node->lChild!=NULL){
        cout<<node->name<<" ";
        TreeNode *temp = node->lChild;
        while(temp!=NULL){
            cout<<temp->name<<" ";
            temp = temp->rChild;
        }
        cout<<endl;
        TreeNode *son = node->lChild->rChild;
        while(son!=NULL){
            showFamily(son);
            son = son->rChild;
        }
    }
}

//清除全部檔案記錄//釋放樹
void freeTree(TreeNode *node){
    if(node==NULL)return;
    freeTree(node->lChild);
    freeTree(node->rChild);
    delete(node);
    node=NULL;
}
void destroyFile(){
    fstream file("family.txt",ios::out);
    cout<<"清除檔案完成"<<endl;
}

//將家譜記錄存盤
// 樹保存到檔案夾
void saveInFile(TreeNode *node){
    ofstream of("family.txt",ios::app);
    if(node==NULL){ 
        of<<"NULL"<<" ";
        return;
    }
    of<<node->name<<" ";
    of.close();
    saveInFile(node->lChild);
    saveInFile(node->rChild);
}


//從檔案讀樹
void readFile(){//把檔案中的樹節點讀進string陣列
    ifstream f("family.txt",ios::in);
    int i = 0;
    while(!f.eof()){
        f>>s[i];
        i++;
    }
    f.close();
}
//建樹
TreeNode* BuildTree(){
    if(s[i]=="NULL"){
        i++;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        return NULL;
    }
    TreeNode *node = new TreeNode;
    node->lChild = node->rChild = NULL;
    node->name = s[i];
    i++;
    node->lChild = BuildTree();
    node->rChild = BuildTree();
    return node;
}


//-------------------------------------------------------

// //用括號表示法輸出家譜二叉樹
void printBinaryTree(TreeNode *node){
    if(node){
        cout<<node->name; //根節點存在就輸出
    }else return; //不存在,則回傳
    if(node->lChild!=NULL||node->rChild!=NULL)cout<<'('; //左右子樹存在任一就輸出(
    else return; //左右子樹都不存在回傳
    if(node->lChild){
        printBinaryTree(node->lChild); //左子樹存在
    }
    if(node->rChild){
        cout<<','; 
        printBinaryTree(node->rChild);
    }
    cout<<')';
}

void ShowSon(TreeNode *node,string name){
    //這里要判斷父親還是母親  父親肯定有左孩子,母親肯定沒左孩子
    TreeNode *parent = Find(node,name);
    if(parent==NULL){cout<<"查無此人"<<endl;return;}
    TreeNode *temp = NULL;
    if(parent->lChild==NULL){//bug這樣有要是你的兄弟沒老婆,會把兄弟當成孩子的 
        temp = parent->rChild;//指向第一個孩子
        cout<<name<<"的孩子是:";
        while(temp!=NULL){
            cout<<temp->name<<" ";
            temp = temp->rChild;
        }
        cout<<endl;
    }else if(parent->lChild!=NULL){
        temp = parent->lChild->rChild;
        cout<<name<<"的孩子是:";
        while(temp!=NULL){
            cout<<temp->name<<" ";
            temp = temp->rChild;
        }
        cout<<endl;
    }
}

// //查找某人的所有祖先(這里的祖先是指所設計的二叉樹結構中某結點的所有祖先結點)
bool ShowAllFather(TreeNode *node,string name){
    if(node==NULL)return false;
    if(node->name==name)return true;
    if(ShowAllFather(node->lChild,name)||ShowAllFather(node->rChild,name)){
        cout<<node->name<<" ";
        return true;
    }
    return false;
}

int main(){
    TreeNode *ancestor = NULL;
    char a;
    while(true){
        cout<<"選擇1創建新家譜,選擇2用檔案中存盤的家譜"<<endl; 
        cin>>a;
        if(a=='1'){
            ancestor = savePerson(); ;
            break;
        }
        else if(a=='2'){
            fstream f("family.txt");
            f.seekg(0,ios::end);
            streampos fp = f.tellg();
            if(int(fp)==0){
                cout<<"檔案為空"<<endl;
            }else{
                readFile();
                ancestor = BuildTree();
                break;
            }
            f.close();
        }
        else cout<<"輸入錯誤"<<endl;
    }

    cout<<"-----------------------------家譜------------------------------"<<endl;
    while(true){
        char choose1 = -1;
        cout<<"按1選擇檔案操作,按2選擇家譜操作,按3退出,你的選擇是:";
        cin>>choose1;
        if(choose1=='1'){
            while(true){
                char choose2 = '-1';
                cout<<"按1選擇輸入家譜,按2選擇輸出家譜,按3選擇清除記錄回傳,按4選擇保存記錄后回傳,你的選擇是:";
                cin>>choose2;
                if(choose2=='1'){
                    if(flag==false){
                        save(ancestor);
                    }else if(flag==true){
                        ancestor = savePerson();
                    }
                }else if(choose2=='2'){
                    if(ancestor==NULL){
                        cout<<"家譜為空"<<endl;
                    }else{
                    showFamily(ancestor);
                    cout<<endl;
                    }
                }else if(choose2=='3'){
                    freeTree(ancestor);
                    destroyFile();
                    ancestor = NULL;
                    flag = true;
                    break;
                }else if(choose2=='4'){
                        if(ancestor==NULL){
                            cout<<"家譜為空"<<endl;
                        }else{
                            //如果不為空,先清空檔案夾
                            fstream f("family.txt",ios::out);
                            f.close();
                            saveInFile(ancestor);
                            cout<<"保存成功"<<endl;
                            break;  
                        }  
                }else {
                    cout<<"輸入錯誤"<<endl;
                }
            }
        }else if(choose1=='2'){
            while(true){
                char choose3 = '-1';
                cout<<"按1選擇括號表示法輸出,按2選擇查找某人的所有兒子,按3選擇查找某人的所有祖先,按4選擇回傳,你的選擇是:";
                cin>>choose3;
                if(choose3=='1'){
                    if(ancestor==NULL){
                        cout<<"家譜為空"<<endl;
                    }else{
                    printBinaryTree(ancestor);
                    cout<<endl;
                    }
                }else if(choose3=='2'){
                    if(ancestor==NULL){
                        cout<<"家譜為空"<<endl;
                    }else{
                    cout<<"請輸入你要查找誰的兒子的名字"<<endl;
                    string s ;
                    cin>>s;
                    ShowSon(ancestor,s);
                    cout<<endl;
                    }
                }else if(choose3=='3'){
                    if(ancestor==NULL){
                        cout<<"家譜為空"<<endl;
                    }else{
                    cout<<"請輸入你要查找誰的全部祖先"<<endl;
                    string s;
                    cin>>s;
                    cout<<s<<"的全部祖先是:";
                    ShowAllFather(ancestor,s);
                    cout<<endl;
                    }
                }else if(choose3=='4'){
                    break;
                }else {
                    cout<<"輸出錯誤"<<endl;
                }
            }
        }else if(choose1=='3'){
            break;
        }else cout<<"輸出錯誤"<<endl;
        cout<<"----------------------------------------------------------"<<endl;
    }

    //------------------------------------------------------------------------
   
    system("pause");
    return 0;
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/231027.html

標籤:其他

上一篇:細說JS中的深拷貝與淺拷貝

下一篇:【ArcGIS風暴】中國756個氣象臺站分布Shapefile資料下載

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more