数据结构学习——树的储存结构
三种表示法:双亲表示法,孩子表示法,孩子兄弟表示法
双亲表示法
//树结构——双亲表示法
#include <iostream>using namespace std;struct Tree
{string data;Tree* parent; //双亲指针Tree* firstchild; //第一个孩子指针Tree* nextsibling; //下一个兄弟指针
};void CreateTree(Tree*&root,string data,Tree* parent)
{Tree* newtree= new Tree;newtree->data=data;newtree->parent=parent;newtree->firstchild=NULL;newtree->nextsibling=NULL;if(root==NULL){root=newtree;return;}if(parent!=NULL){//temp指向该父类的第一个孩子Tree* temp=parent->firstchild;//如果第一个孩子为空,添加为第一个孩子if (temp==NULL){parent->firstchild=newtree;}else{//不为空的情况下//如果该父类有兄弟,就遍历到最后一个兄弟,然后添加为兄弟while(temp->nextsibling!=NULL){temp=temp->nextsibling;}temp->nextsibling=newtree;}}
}//前序便利
void printTree(Tree* root){if(root==NULL){return;}else{cout<<root->data<<endl;printTree(root->firstchild);printTree(root->nextsibling);}}int main(){Tree* root=NULL;CreateTree(root,"root",NULL);CreateTree(root,"root->node1",root);CreateTree(root,"root->node2",root);CreateTree(root,"root->node3",root);CreateTree(root,"root->node1->node1",root->firstchild);CreateTree(root,"root->node1->node2",root->firstchild);CreateTree(root,"root->node2->node1",root->firstchild->nextsibling);CreateTree(root,"root->node3->node1",root->firstchild->nextsibling->nextsibling);cout<<"树的结构为:"<<endl;printTree(root);return 0;}
好吧这个其实是个综合的表示法,是孩子兄弟加上一个parent指针
孩子表示法
(虽然我感觉看这张图理解可能也会有点晕)
//孩子表示法
#include<iostream>using namespace std;
//这里要先声明,不然Childlist中引用会出错
struct TreeNode;/*
简单说一下这里的思路:
TreeNode结构体代表一个节点,data为数据,firstChild为指向第一个孩子的指针
一个节点的孩子我们用Childlist链表来表示,
链表中的每个节点都有一个指向TreeNode的指针和指向下一位的指针createTree函数创建一个新的节点并返回
addChild函数将返回的节点通过识别两个参数,
第一个是你想要插入位置的父节点,第二个是你想要插入的节点所有的节点都要先createTree再addChild,
*/struct Childlist{TreeNode* child;Childlist* next;
};struct TreeNode{string data;Childlist* firstChild;};TreeNode* createTree(string data){ TreeNode* newnode=new TreeNode();newnode->data=data;newnode->firstChild=NULL;return newnode;
}void addChild(TreeNode* parent,TreeNode* your_node){if(parent==NULL){return;}Childlist* newnode=new Childlist();newnode->child=your_node;newnode->next=NULL;if(parent->firstChild==NULL){parent->firstChild=newnode;}else{Childlist* temp=parent->firstChild;while(temp->next!=NULL){temp=temp->next;}temp->next=newnode;}}void printTree(TreeNode* root){if(root==NULL){return;}cout<<root->data<<endl;Childlist* temp=root->firstChild;while(temp!=NULL){printTree(temp->child);temp=temp->next;}
}int main(){//测试可看出为前序便利TreeNode* root=createTree("root");TreeNode* child1=createTree("root->child1");TreeNode* child2=createTree("root->child2");TreeNode* child3=createTree("root->child2->child3");TreeNode* child4=createTree("root->child1->child4");TreeNode* child5=createTree("root->child1->child4->child5");TreeNode* child6=createTree("root->child1->child4->child6");TreeNode* child7=createTree("root->child1->child7");addChild(root,child1);addChild(root,child2);addChild(child2,child3);addChild(child1,child4);addChild(child4,child5);addChild(child4,child6);addChild(child1,child7);printTree(root);return 0;
}
孩子兄弟表示法
//孩子兄弟表示法
//其实原理和孩子表示法差不多,只不过是把孩子表示法中的链表提到了节点上
//类似于一个二叉树
//还有就是感觉先定义然后再链接感觉更直观一点
#include<iostream>using namespace std;struct TreeNode{string data;TreeNode* firstchild;TreeNode* next;
};TreeNode* createTree(string data){TreeNode* newnode = new TreeNode;newnode->data = data;newnode->firstchild = NULL;newnode->next = NULL;return newnode;
}void addNode(TreeNode* parent,TreeNode* your_node){if(parent->firstchild == NULL){parent->firstchild = your_node;}else{TreeNode* temp = parent->firstchild;while(temp->next != NULL){temp = temp->next;}temp->next = your_node;}}void printTree(TreeNode* root){if(root == NULL){return;}cout<<root->data<<endl;TreeNode* temp = root->firstchild;while(temp != NULL){printTree(temp);temp = temp->next;}
}int main(){TreeNode* root = createTree("root");TreeNode* node1 = createTree("root->ndoe1");TreeNode* node2 = createTree("root->node2");TreeNode* node3 = createTree("root->node2->node3");TreeNode* node4 = createTree("root->node2->node4");addNode(root,node1);addNode(root,node2);addNode(node2,node3);addNode(node2,node4);printTree(root);return 0;
}