家谱Project由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“家谱常用的字”。
Project3 家谱管理系统
年级:2014级 学院:电子与信息工程学院 班级:智能科学与技术、自动化 姓名:王金顶 14350046 姓名:王帆 14350045 姓名:张宇航 14350069
【题目要求】
用树形结构实现家族成员信息管理(如建立、删除、查询、统计、打印等)。
【实现功能】
该程序采用二叉树结构进行家谱的各种操作。二叉树的结构为:男性的左子树为他的兄第姐妹,右子树为他的妻子。妻子节点的左子树为她的孩子,右子树为其他妻子(丈夫再婚)。
程序可以读入文件并依据文件内容建立家谱,或者通过手动输入一个节点一个节点的添加建立家谱。
家谱的操作分为6大类:添加成员、删除成员、查询成员、统计成员、打印成员、修改成员信息。
1.添加成员分为2类:添加妻子(需知道丈夫姓名)、添加孩子(需知道母亲姓名)。
2.删除成员分为1类:删除成员(需知道其姓名)并删除他的妻子和孩子。3.查询成员分为4类:查询单个成员并输出(需知道其姓名)、查询成员及其家庭并输出(妻子和孩子)(需知道其姓名)、查询成员父母并输出(需知道其姓名)、查询某代的所有成员并输出。
4.统计成员分为2类:统计平均年龄、统计总人数。5.打印成员分为4类:前序打印、中序打印、后序打印、以目录的形式打印。6.修改成员信息分为6类(需知道其姓名):修改姓名、修改性别、修改生命状态、修改出生年份、修改死亡年份、修改婚姻状态。
程序也可以将二叉树以前序的方式写入文件中,并且这个文件能够被该程序还原为二叉树再次进行操作。
【数据结构与算法】
节点采用结构体进行表示: struct Binary_member_node{
string name;
//姓名
int sex;
//性别(1男、0女)
int state;
//生命状态(0健在、1已故)
int born_date;
//出生日期
int dead_date;
//死亡日期(若已死亡)
int married;
//婚姻状况(2离婚、1已婚、0未婚)
int iswife;
//是否是妻子(1是、0不是)
int generation;
//第几代人
Binary_member_node* left;
//左节点(兄弟姐妹)
Binary_member_node* right;
//右节点(妻子)
Binary_member_node* up;
//父节点
Binary_member_node();
//构造函数
Binary_member_node(string name1, int sex1, int state1, int born, int dead, int
married1, int iswife1);
//构造函数 };
图1 文件读入流程图
图2 手动输入流程图
图3 菜单栏流程图
文件输入问题的解决:
文件输入函数最初一直无法成功的问题在于我们不知道到底怎样让文件以一种特殊格式存储使得我们重新读取时可以识别并创建二叉树,成功的关键在于节点左右指针的存储。我们发现将二叉树以前序的格式递归存储时,如果加上存储左右指针,就可以以前序的格式进行递归读取,并通过判断左右指针是否为空选择将下一行读取到相应位置,但我们发现存储指针时,读取很不方便,因此我们在指针不为空时存入123,为空时存入0,问题完美解决!文件输入代码如下:
Error_code Family_tree::readFile(Binary_member_node* &sub_root){
if(!iFile)
{
cout
iFile.close();
return fail;
}
else
{
read_node(sub_root,NULL);
iFile.close();
return succe;
} } Void Family_tree::read_node(Binary_member_node*&sub_root, Binary_member_node* upNode){
string name1;
int sex1;
int state1;
int born;int dead;int married1;int iswife1;int generation1;int left;int right;iFile>>name1>>sex1>>state1>>born>>dead>>married1>>iswife1>>generation1>>left>>right;
Binary_member_node* temp = new Binary_member_node(name1,sex1,state1,born,dead,married1,iswife1);
temp->generation = generation1;
temp->up = upNode;
sub_root = temp;
if(left!=0)
read_node(sub_root->left, sub_root);
else
sub_root->left = NULL;
if(right!=0)
read_node(sub_root->right, sub_root);
else
sub_root->right = NULL;}
文件存储代码为:
Error_code Family_tree::writeFile(Binary_member_node* &sub_root){
if(!oFile)
{
cout
oFile.close();
return fail;
}
else
{
write_node(sub_root);
oFile.close();
return succe;
} } void Family_tree::write_node(Binary_member_node* &sub_root){
if(sub_root)
{
oFilenamesexstateborn_datedead_datemarriediswifegeneration
if(sub_root->left)
oFile
else
oFile
if(sub_root->right)
oFile
else
oFile
write_node(sub_root->left);
write_node(sub_root->right);
} }
【测试数据、结果及分析】
一、添加成员功能测试
图4 为毛恩农添加妻子张氏
图5 为江青添加儿子毛毛
图6 进入查询成员界面,查询毛毛的信息并打印
结论:程序运行良好,无错误现象。
二、删除成员功能测试
图7 删除家谱中的成员毛毛,并查询毛毛是否在家谱中
结论:程序运行良好,无错误现象。
三、查询成员功能测试
图8 查询毛岸英的信息以及毛岸英父母的信息
图9 查询毛东东的父母
图10 查询第二代所有成员信息
结论:程序运行良好,无错误现象。
四、统计查询成员功能测试
图11 统计总人数
图12 统计平均年龄
结论:程序运行良好,无错误现象。
五、打印查询成员功能测试
图13 前序打印
图14 中序打印
图15 后序打印
图16 目录格式打印
结论:程序运行良好,无错误现象。
六、修改查询成员信息功能测试
图17 毛岸英修改前的信息
图18 对毛岸英的信息进行修改
图19 查询被修改后的信息
结论:程序运行良好,无错误现象。
【分工、贡献%、自我评分】
王金顶:算法设计、程序调试、实验报告 40% 100分 张宇航:算法设计、程序测试、实验报告 30% 100分 王帆:算法设计、流程图、实验报告 30% 100分
【项目总结】
本次的项目较为复杂繁琐,进行家谱的操作需要几十个函数来完成,在这么多函数中,以文件输入输出、通过名字找到节点比较困难。我们也在这次的打代码过程中充分意识到了类的强大,这次试验也让我们掌握了更多的知识和技巧,给我们提供了一次难得的实战经验。
【文件内容样例】 read.txt 毛祖人 1 1 1823 1893 1 0 1 0 123 周氏 0 1 1820 1876 1 1 1 123 0 毛恩农 1 1 1841 1900 1 0 2 123 0 毛恩普 1 1 1846 1904 1 0 2 0 123 刘氏 0 1 1846 1884 1 1 2 123 0 毛贻昌 1 1 1870 1920 1 0 3 0 123 文素勤 0 1 1872 1919 1 1 3 123 0 毛泽东 1 1 1893 1976 1 0 4 123 123 毛泽民 1 1 1896 1943 1 0 4 123 0 毛泽覃 1 1 1905 1935 0 0 4 0 0 罗氏 0 1 1889 1910 1 1 4 0 123 杨开慧 0 1 1901 1930 1 1 4 123 123 毛岸英 1 1 1922 1950 1 0 5 123 0 毛岸青 1 1 1923 2007 1 0 5 0 123 邵华 0 1 1924 2005 1 1 5 123 0 毛新宇 1 0 1970 0 1 0 6 0 123 刘滨 0 0 1977 0 1 1 6 123 0 毛东东 1 0 2003 0 0 0 7 123 0 毛甜懿 0 0 2008 0 0 0 7 0 0 贺子珍 0 1 1909 1984 1 1 4 0 123 江青 0 1 1914 1991 1 1 4 123 0 李讷 0 0 1940 0 1 0 5 0 0 【程序清单】
1.Family_tree.h(家谱类的声明)
#include #include #include using namespace std;
enum Error_code{succe,fail,not_present};//成功,未找到 const int current_year = 2016;
struct Binary_member_node{
string name;//姓名
int sex;//性别(1男、0女)
int state;//生命状态(0健在、1已故)int born_date;//出生日期
int dead_date;//死亡日期(若已死亡)
int married;//婚姻状况(2离婚、1已婚、0未婚)int iswife;//是否是妻子(1是、0不是)int generation;//第几代人
Binary_member_node* left;//左节点(兄弟姐妹)Binary_member_node* right;//右节点(妻子)Binary_member_node* up;//父节点 Binary_member_node();Binary_member_node(string name1, int sex1, int state1, int born, int dead, int married1, int iswife1);};cla Family_tree{ public: //基本函数
Family_tree();//构造函数,对二叉树进行初始化 void creat_node(Binary_member_node* &sub_root);//创建一个节点
bool empty()const;//判断二叉树是否为空 void destroy_Family_tree(Binary_member_node* &sub_root);//递归删除一个二叉树 ~Family_tree();//析构函数
Error_code modify_member_name(Binary_member_node* &sub_root, string name1);//修改名字
Error_code modify_member_sex(Binary_member_node* &sub_root, int sex1);//修改性别
Error_code modify_member_state(Binary_member_node* &sub_root, int state1);//修改生命状态 Error_code modify_member_born_date(Binary_member_node* &sub_root, int born_date1);//修改出生日期 Error_code modify_member_dead_date(Binary_member_node* &sub_root, int dead_date1);//修改死亡日期
Error_code modify_member_married(Binary_member_node* &sub_root, int married1);//修改婚姻状态
//家谱成员操作
Error_code delete_member(Binary_member_node* &sub_root);//删除某人(若其还有后代,则一并删除)。
Error_code add_child(Binary_member_node* sub_root, Binary_member_node* child);//某人添加孩子(sub_root为妻子节点)Error_code add_wife(Binary_member_node* sub_root, Binary_member_node* wife);//某人娶妻或再娶妻(sub_root为丈夫节点)
//查找信息函数
Binary_member_node* find_by_name(Binary_member_node* sub_root, string &name1)const;//按照姓名查询并输出节点信息(可以有重名)
void find_name(Binary_member_node* &target, Binary_member_node* sub_root,string &name1)const;void find_parents(Binary_member_node* sub_root);//通过名字寻找父母并打印
void output_node(Binary_member_node* &sub_root)const;//显示一个节点的信息 void output_family_node(Binary_member_node* &sub_root);//显示一个小家庭信息(包括其本人、妻子、孩子的信息)
void find_nth_generation(Binary_member_node* &sub_root, int n)const;//显示第 n 代所有人的信息
int total_age(Binary_member_node* &sub_root)const;//统计平均年龄
int people_number(Binary_member_node* &sub_root)const;//统计总人数
//显示操作信息函数 void main_meage();void add_member_meage();void delete_member_meage();void ask_member_meage();void count_member_meage();void print_member_meage();void modify_member_meage();
//输入输出函数
void preorder(Binary_member_node* &sub_root)const;//先序遍历 void inorder(Binary_member_node* &sub_root)const;//中序遍历 void postorder(Binary_member_node* &sub_root)const;//后序遍历 void print_name_content(Binary_member_node* &sub_root)const;//目录格式输出
//文件输入输出函数
Error_code readFile(Binary_member_node* &sub_root);void read_node(Binary_member_node* &sub_root,Binary_member_node* upNode);Error_code writeFile(Binary_member_node* &sub_root);void write_node(Binary_member_node* &sub_root);private: Binary_member_node *root;//指向根节点的指针 };
2.family_tree.cpp(类的函数实现)
#include #include #include #include“family_tree.h” using namespace std;
ifstream iFile(“read.txt”);ofstream oFile(“family.txt”);Binary_member_node::Binary_member_node(){ name = “”;sex =-1;state =-1;born_date = 0;dead_date = 0;married =-1;iswife = 0;generation = 0;left = right = up = NULL;} Binary_member_node::Binary_member_node(string name1, int sex1, int state1, int born, int dead, int married1, int iswife1){ name = name1;sex = sex1;state = state1;born_date = born;dead_date = dead;married = married1;iswife = iswife1;left = right = up = NULL;}
/************************************************************************************************/ Family_tree::Family_tree(){ root = NULL;} void Family_tree::creat_node(Binary_member_node* &sub_root){ string name1;int sex1;int state1;int born;int dead;int married1;
cout>name1;cout>sex1;cout>state1;cout>born;
if(state1 == 1){
cout
cin>>dead;} else dead = 0;
cout>married1;
Binary_member_node* temp = new Binary_member_node(name1,sex1,state1,born,dead,married1,0);temp->generation = 1;sub_root = temp;} Family_tree::~Family_tree(){ destroy_Family_tree(root);} void Family_tree::destroy_Family_tree(Binary_member_node* &sub_root){ if(sub_root){ destroy_Family_tree(sub_root->left);destroy_Family_tree(sub_root->right);delete sub_root;sub_root = NULL;} } bool Family_tree::empty()const { return(root == NULL);} Error_code Family_tree::modify_member_name(Binary_member_node* &sub_root, string name1){ sub_root->name = name1;if(sub_root->name == name1)return succe;else return fail;} Error_code Family_tree::modify_member_sex(Binary_member_node* &sub_root, int sex1){ sub_root->sex = sex1;if(sub_root->sex == sex1)return succe;else return fail;} Error_code Family_tree::modify_member_state(Binary_member_node* &sub_root, int state1){ sub_root->state = state1;if(sub_root->state == state1)return succe;else return fail;} Error_code Family_tree::modify_member_born_date(Binary_member_node* &sub_root, int born_date1){ sub_root->born_date = born_date1;if(sub_root->born_date == born_date1)return succe;else return fail;} Error_code Family_tree::modify_member_dead_date(Binary_member_node* &sub_root, int dead_date1){ sub_root->dead_date = dead_date1;if(sub_root->dead_date == dead_date1)return succe;else return fail;} Error_code Family_tree::modify_member_married(Binary_member_node* &sub_root, int married1){ sub_root->married = married1;if(sub_root->married == married1)return succe;else return fail;}
/****************************************************************************************************/ Error_code Family_tree::delete_member(Binary_member_node* &sub_root){ if(sub_root){
Binary_member_node* fatherNode = sub_root->up;fatherNode->left = sub_root->left;destroy_Family_tree(sub_root->right);delete sub_root;sub_root = NULL;return succe;} else return fail;} Error_code Family_tree::add_child(Binary_member_node* sub_root, Binary_member_node* child){ Binary_member_node* temp = sub_root;if(temp){
while(temp->left){
temp = temp->left;} temp->left = child;child->up = temp;child->generation = sub_root->generation + 1;return succe;} else return fail;} Error_code Family_tree::add_wife(Binary_member_node* sub_root, Binary_member_node* wife){ sub_root->married = 1;Binary_member_node* temp = sub_root;if(temp){
while(temp->right){
temp = temp->right;} temp->right = wife;wife->up = temp;wife->iswife = 1;wife->married = 1;wife->generation = sub_root->generation;return succe;} else return fail;}
/****************************************************************************************************/ void Family_tree::find_name(Binary_member_node* &target, Binary_member_node* sub_root, string &name1)const { if(sub_root){
if(sub_root->name == name1)
target = sub_root;else {
find_name(target, sub_root->left, name1);
find_name(target, sub_root->right, name1);} } } Binary_member_node* Family_tree::find_by_name(Binary_member_node* sub_root, string &name1)const { Binary_member_node* target = NULL;find_name(target,sub_root,name1);if(target)return target;return NULL;} void Family_tree::find_parents(Binary_member_node* sub_root){ if(sub_root!= root && sub_root->iswife == 0){
Binary_member_node* temp1 = sub_root->up;while(temp1->iswife == 0){
temp1 = temp1->up;}//temp1为母亲节点
Binary_member_node* temp2 = temp1->up;while(temp2->iswife == 1){
temp2 = temp2->up;}//temp2为父亲节点
output_node(temp2);output_node(temp1);} else cout
coutname;
if(sub_root->sex==1)
cout
else
cout
if(sub_root->state == 0)
{
coutborn_dateborn_date;
}
else
coutborn_datedead_date
sub_root->dead_date-sub_root->born_date
if(sub_root->married == 0)
cout
else if(sub_root->married == 1)
cout
else
coutmarried!= 0){
Binary_member_node* temp;
Binary_member_node* temp2;
if(sub_root->iswife == 0)
{
temp = sub_root->right;
while(temp){
cout
output_node(temp);
temp2 = temp->left;
cout
if(!temp2)
cout
while(temp2){
output_node(temp2);
temp2 = temp2->left;
}
temp = temp->right;
}
}
else
{
cout
temp = sub_root->up;
while(temp->iswife == 1){
temp = temp->up;
}
output_node(temp);
cout
temp2 = sub_root->left;
if(!temp2)
cout
while(temp2){
output_node(temp2);
temp2 = temp2->left;
}
} } } int Family_tree::total_age(Binary_member_node* &sub_root)const { if(!sub_root)return 0;else return total_age(sub_root->left)+ total_age(sub_root->right)+(sub_root->state==0?current_year-sub_root->born_date:sub_root->dead_date-sub_root->born_date);} int Family_tree::people_number(Binary_member_node* &sub_root)const { if(!sub_root)return 0;else return people_number(sub_root->left)+people_number(sub_root->right)+1;}
void Family_tree::find_nth_generation(Binary_member_node* &sub_root, int n)const { if(sub_root){
if(sub_root->generation == n){
output_node(sub_root);} if(sub_root->left)
find_nth_generation(sub_root->left, n);
if(sub_root->right)
find_nth_generation(sub_root->right, n);} } /*******************************************************************************************************/ void Family_tree::main_meage(){ cout
/****************************************************************************************/ void Family_tree::inorder(Binary_member_node* &sub_root)const { if(sub_root!= NULL){ inorder(sub_root->left);output_node(sub_root);inorder(sub_root->right);} } void Family_tree::preorder(Binary_member_node* &sub_root)const { if(sub_root!= NULL){ output_node(sub_root);preorder(sub_root->left);preorder(sub_root->right);} } void Family_tree::postorder(Binary_member_node* &sub_root)const { if(sub_root!= NULL){ postorder(sub_root->left);postorder(sub_root->right);output_node(sub_root);} } void Family_tree::print_name_content(Binary_member_node* &sub_root)const { if(sub_root){ for(int i=1;igeneration;i++)coutnameleft);print_name_content(sub_root->right);} }
/***************************************************************************************/ Error_code Family_tree::readFile(Binary_member_node* &sub_root){ if(!iFile){ cout>name1>>sex1>>state1>>born>>dead>>married1>>iswife1>>generation1>>left>>right;Binary_member_node* temp = new Binary_member_node(name1,sex1,state1,born,dead,married1,iswife1);temp->generation = generation1;temp->up = upNode;sub_root = temp;if(left!=0)read_node(sub_root->left, sub_root);else sub_root->left = NULL;if(right!=0)read_node(sub_root->right, sub_root);else sub_root->right = NULL;} Error_code Family_tree::writeFile(Binary_member_node* &sub_root){ if(!oFile){ coutnamesexstateborn_datedead_datemarriediswifegenerationleft)oFileright)oFileleft);write_node(sub_root->right);} }
三、Family.cpp(主函数)#include #include #include #include“family_tree.h”
int main(){
1已故)
婚、1已婚、0未婚)
树
手动输入
树
点信息来建立二叉树
string new_name;//姓名
int new_sex;//性别(1男、0女)int new_state;//生命状态(0健在、int new_born_date;//出生日期 int new_dead_date;//死亡日期(若已死亡)int new_married;//婚姻状况(2离
string name;int nth;
int totalage;
int people_number;Error_code result;
Binary_member_node* root = NULL;Binary_member_node* wife = NULL;Binary_member_node* child = NULL;Binary_member_node* temp = NULL;
Family_tree family_tree;//建立一棵家谱二叉int choice;//选择文件输入还是cout>choice;if(choice == 0){
if(family_tree.readFile(root)== succe)cout
cout
cout
family_tree.creat_node(root);//通过输入根节} int main_choice;int add_choice;int delete_choice;int modify_choice;int ask_choice;int count_choice;int print_choice;family_tree.main_meage();cin>> main_choice;while(main_choice!= 7){
if(main_choice == 1)
{
family_tree.add_member_meage();
cin>>add_choice;
while(add_choice!= 3){
if(add_choice == 1)
{
cout
cin>>name;
temp = family_tree.find_by_name(root,name);
if(temp)
{
family_tree.creat_node(wife);
if(family_tree.add_wife(temp,wife)== succe)
cout
else
{
cout
delete wife;
}
}
else
cout
}
else if(add_choice == 2)
{
cout
cin>>name;
temp = family_tree.find_by_name(root,name);
if(temp)
{
family_tree.creat_node(child);
if(family_tree.add_child(temp,child)== succe)
cout
else
{
cout
delete child;
}
}
else
cout
}
else
break;
family_tree.add_member_meage();
cin>>add_choice;
}
}
else if(main_choice == 2)
{
family_tree.delete_member_meage();
cin>>delete_choice;
while(delete_choice!= 2){
if(delete_choice == 1)
{
cout
cin>>name;
temp = family_tree.find_by_name(root,name);
if(temp)
{
if(family_tree.delete_member(temp)== succe)
cout
else
cout
}
else
cout
}
else
break;
family_tree.delete_member_meage();
cin>>delete_choice;
}
}
else if(main_choice == 3)
{
family_tree.ask_member_meage();
cin>>ask_choice;
while(ask_choice!= 5){
if(ask_choice == 1)
{
cout
cin>>name;
temp = family_tree.find_by_name(root,name);
if(temp)
family_tree.output_node(temp);
else
cout
}
else if(ask_choice == 2)
{
cout
cin>>name;
temp = family_tree.find_by_name(root,name);
if(temp)
family_tree.output_family_node(temp);
else
cout
}
else if(ask_choice == 3)
{
cout
cin>>name;
temp = family_tree.find_by_name(root,name);
if(temp)
family_tree.find_parents(temp);
else
cout
}
else if(ask_choice == 4)
{
cout
cin>> nth;
family_tree.find_nth_generation(root,nth);
}
else
break;
family_tree.ask_member_meage();
cin>>ask_choice;
}
}
else if(main_choice == 4)
{
family_tree.count_member_meage();
cin>>count_choice;
while(count_choice!= 3){
if(count_choice == 1)
{
people_number = family_tree.people_number(root);
cout
}
else if(count_choice == 2)
{
totalage = family_tree.total_age(root);
people_number = family_tree.people_number(root);
cout
}
else
break;
family_tree.count_member_meage();
cin>>count_choice;
}
}
else if(main_choice == 5)
{
family_tree.print_member_meage();
cin>>print_choice;
while(print_choice!= 5){
if(print_choice == 1)
family_tree.preorder(root);
else if(print_choice == 2)
family_tree.inorder(root);
else if(print_choice == 3)
family_tree.postorder(root);
else if(print_choice == 4)
family_tree.print_name_content(root);
else
break;
family_tree.print_member_meage();
cin>>print_choice;
}
}
else if(main_choice == 6)
{
family_tree.modify_member_meage();
cin>>modify_choice;
cout
cin>>name;
temp = family_tree.find_by_name(root,name);
if(temp)
{
while(modify_choice!= 7){
if(modify_choice == 1)
{
cout
cin>>new_name;
if(family_tree.modify_member_name(temp,new_name)== succe)
cout
else
cout
}
else if(modify_choice == 2)
{
cout
cin>>new_sex;
if(family_tree.modify_member_sex(temp,new_sex)== succe)
cout
else
cout
}
else if(modify_choice == 3)
{
cout
cin>>new_state;
if(family_tree.modify_member_state(temp,new_state)== succe)
{
if(new_state == 1)
{
cout
cin>>new_dead_date;
family_tree.modify_member_dead_date(temp,new_dead_date);
}
cout
}
else
cout
}
else if(modify_choice == 4)
{
cout
cin>>new_born_date;
if(family_tree.modify_member_born_date(temp,new_born_date)== succe)
cout
else
cout
}
else if(modify_choice == 5)
{
cout
cin>>new_dead_date;
if(family_tree.modify_member_dead_date(temp,new_dead_date)== succe)
cout
else
cout
}
else if(modify_choice == 6)
{
cout
cin>>new_married;
if(family_tree.modify_member_married(temp,new_married)== succe)
cout
else
cout
}
else
break;
family_tree.modify_member_meage();
cin>>modify_choice;
}
}
else
cout
}
else
break;
family_tree.main_meage();cin>> main_choice;} cout>save;if(save == 'N' || save == 'n');else { if(family_tree.writeFile(root)== succe)cout
return 0;}
四、各4S店普遍存在的问题:1.4S的经营理念没有完全体现:首先,在欧美4S品牌的统计中,整车销售、配件、维修的比例是2∶1∶4,汽车销售及服务的利润超过了汽车生产利润,成为汽车第一大......
家谱学.txt如果有来生,要做一棵树,站成永恒,没有悲伤的姿势。一半在土里安详,一半在风里飞扬,一半洒落阴凉,一半沐浴阳光,非常沉默非常骄傲,从不依靠从不寻找。家谱学.txt生活是过出......
后 记我族第八次重修家谱历时一年半,在编委会编撰人员的竭诚尽力、不辞劳苦、夜以继日、潜心编修下,于2012年秋出版,与大家见面了。家谱编撰,看似简单,实很繁杂。从开始的策划,召......
家谱文化我们中国人自古以来就有祭祖的习俗,每逢旧历年节,不仅举家团聚,而且还往往要祭奠先人。“先人”不仅包括我们幼时曾承欢膝下、现已故去的长辈,还会上溯很多代,甚至直到最......
后 记家谱编撰,看似简单,实则很繁杂。经过一年多时间的收集、整理、核对,《我的家世》一书,今天终于和大家见面了。此书的出版,以家谱为基础,将内容进一步充实、完善、扩展、延伸......