对于普通树实现的细节包括

1 树结点的结构体

2 初始化及删除树结点(关注内存泄露)

3 递归先序遍历

4 通过关键值的查询操作,返回关键值的结点

5 凹入表实现

6 广义表实现

7 非递归先序遍历,利用栈作为辅助的数据结构

 #include <iostream>
#include <crtdbg.h>
#include <cstring>
#include <assert.h>
using namespace std; typedef int DataType;
struct TreeNode
{
TreeNode()
{
sibling = NULL;
child = NULL;
}
DataType data;
TreeNode * sibling; //右兄弟结点
TreeNode * child; //左子结点
};
typedef TreeNode *DataStack; // 存储类型为 TreeNode*
//普通树
class Tree
{
private:
TreeNode *root;
Tree(const Tree &) {}//防止拷贝构造 与 赋值
Tree & operator=(const Tree &) { return *this; }
public:
Tree(const DataType &data);
~Tree();
const TreeNode * GetRoot()const { return root;}
TreeNode * GetRoot() { return root;}
void Init(const DataType &data);
void Destroy(TreeNode * p);//删除根结点
void DestroySub(TreeNode * p);//删除子结点;
TreeNode * InsertChild(TreeNode *p, DataType data);
TreeNode * InsertSibling(TreeNode *p, DataType data);
void Print(const TreeNode * p); //先序遍历
TreeNode * Find(TreeNode * p, DataType data);//寻找data返回并返回结点
void Print2(); //非递归先序遍历
};
//辅助类栈
class Stack
{
private:
struct Node
{
DataStack data;
Node *next;
};
Node * head;
void Init()
{
head = NULL;
}
void Destroy()
{
for (Node* p = head; p != NULL;)
{
Node *pTemp = p->next;
delete p ;
p = pTemp;
}
head = NULL;
}
public:
Stack()
{
Init();
}
~Stack()
{
Destroy();
}
void Push(DataStack data)
{
Node *p = new Node;
p->data = data;
p->next = head;
head = p;
}
DataStack Pop()
{
if (head == NULL)
{
return NULL;
}
Node *p = head;
DataStack temp = p->data;
head = head->next;
delete p;
p = NULL;
return temp;
}
int Getlenth()
{
int n = ;
for (Node *p = head; p != NULL; p = p->next)
{
++n;
}
return n;
}
DataStack Getop()
{
if (head == NULL)
{
return NULL;
}
return head->data;
}
bool Empty()
{
return (head == NULL);
}
};
//普通树方法实现
Tree::Tree(const DataType &data)
{
Init(data);
}
Tree::~Tree ()
{
Destroy(root);
}
void Tree::Init(const DataType &data)
{
root = new TreeNode;
root->child = NULL;
root->sibling = NULL;
root->data = data;
}
void Tree::Destroy(TreeNode * p)
{
if (p == NULL)
{
return;
}
Destroy(p->sibling);
Destroy(p->child);
delete p;
p = NULL;
}
void Tree::DestroySub(TreeNode * p)
{
if (p->child)
{
Destroy(p->child);
p->child = NULL;
}
}
TreeNode * Tree::InsertChild(TreeNode * p, DataType data)
{
if (p->child)
{
return p->child; //已有子结点
}
TreeNode *pNew = new TreeNode;
pNew->data = data;
p->child = pNew;
return pNew;
}
TreeNode * Tree::InsertSibling(TreeNode * p, DataType data)
{
if (p->sibling)
{
return p->sibling;//已有兄弟结点
}
TreeNode *pNew = new TreeNode;
pNew->data = data;
p->sibling = pNew;
return pNew;
}
//先序遍历
void Tree::Print(const TreeNode * p)
{
if(p==NULL)
{
return;
}
cout << p->data << endl;
Print(p->child);
Print(p->sibling);
}
//寻找data并返回结点
TreeNode * Tree::Find(TreeNode * p, DataType data)
{
if(p == NULL)
return NULL;
if (p->data == data)
{
return p;
}
TreeNode *pFind = Find(p->child, data);
if (pFind != NULL)
{
return pFind;
} return Find(p->sibling, data);
}
//非递归先序遍历
void Tree::Print2()
{
TreeNode *p = GetRoot();
if (p == NULL)
{
return;
}
Stack stack; while( (p != NULL) || (!stack.Empty()) )
{
if (p != NULL)
{
cout << p->data << endl;
stack.Push(p);
p = p->child;
}
else
{
p = stack.Pop();
p = p->sibling;
}
}
}
void AoRuBiao(const TreeNode *p, int depth)
{
if (p == NULL)
{
return;
}
for (int i=; i<depth; ++i)
{
cout << " ";
}
cout << p->data;
for (int i=; i<-depth; ++i)
{
cout << " - ";
}
cout << endl;
AoRuBiao(p->child, depth+);
AoRuBiao(p->sibling, depth);
}
void GuangYiBiao(const TreeNode *p)
{
if (p == NULL)
{
return;
}
cout << p->data;
if (p->child)
{
cout << "(";
}
GuangYiBiao(p->child);
if (p->child)
{
cout << ")";
}
if (p->sibling)
{
cout << ",";
}
GuangYiBiao(p->sibling);
} void main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); Tree tree(); //Stack s;
//s.Push(tree.GetRoot());
//cout << s.Getop()->data; TreeNode * p11 = tree.InsertChild(tree.GetRoot(), );
TreeNode * p12 = tree.InsertSibling(p11,);
TreeNode * p13 = tree.InsertSibling(p12,); TreeNode * p111 = tree.InsertChild(p11, );
TreeNode * p112 = tree.InsertSibling(p111,); TreeNode * p121 = tree.InsertChild(p12, );
TreeNode * p122 = tree.InsertSibling(p121,); tree.Print(tree.GetRoot());
//tree.DestroySub(p12);
//tree.Print(tree.GetRoot());
cout << "\n\nSearch p12" << endl;
TreeNode * temp = tree.Find(tree.GetRoot(),);
if (temp != NULL)
{
cout << temp->child->data <<endl;
cout << temp->sibling->data << endl;
} cout << "\n\nAoRuBiao " << endl;
AoRuBiao(tree.GetRoot(),); cout << "\nGuangYiBiao" << endl;
GuangYiBiao(tree.GetRoot()); cout << "\n\n非递归遍历" << endl;
tree.Print2(); system("pause");
}

(转载请注明作者和出处^_*  Seven++ http://www.cnblogs.com/sevenPP/  )

普通树(有根树)C++的更多相关文章

  1. bzoj 4765: 普通计算姬 主席树+替罪羊树思想

    题目大意: 给定一棵\(n\)个节点的带权树有根树,设\(sum_p\)表示以点\(p\)为根的这棵子树中所有节点的权 计算姬支持下列两种操作: 给定两个整数\(u,v\),修改点\(u\)的权值为\ ...

  2. 再谈树---无根树转有根树( dfs搜索转化+fa数组记录父节点) *【模板】

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include <vector> ...

  3. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  4. BZOJ4551——[Tjoi2016&Heoi2016]树

    1.题意: 给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个 结点,可以打多次标记.)2. 询问操作:询问某个 ...

  5. HDU 4605 Magic Ball Game (dfs+离线树状数组)

    题意:给你一颗有根树,它的孩子要么只有两个,要么没有,且每个点都有一个权值w. 接着给你一个权值为x的球,它从更节点开始向下掉,有三种情况 x=w[now]:停在此点 x<w[now]:当有孩子 ...

  6. Educational Codeforces Round 6 E dfs序+线段树

    题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...

  7. HYSBZ 4551 (树状数组) 采花

    题目:这里 题意: 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记, ...

  8. BZOJ 4551: [Tjoi2016&Heoi2016]树

    4551: [Tjoi2016&Heoi2016]树 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 748  Solved: 394[Subm ...

  9. [bzoj4551][Tjoi2016][Heoi2016]树

    Description 在2016年,佳媛姐姐刚刚学习了树,非常开心. 现在她想解决这样一个问题:给定一颗有根树(根为1),有以下两种操作: 1. 标记操作:对某个结点打上标记(在最开始,只有结点1有 ...

随机推荐

  1. MKMapView的内存释放问题

    MKMapView的内存释放问题 by 伍雪颖 - (void)dealloc { self.mapView.showsUserLocation = NO; self.mapView.userTrac ...

  2. 使用Java高速实现进度条

    基于有人问到如何做进度条,以下给个简单的做法: 主要是使用JProgressBar(Swing内置javax.swing.JProgressBar)和SwingWorker(Swing内置javax. ...

  3. Outlook2010 移动数据文件到其它地方

            您可以将数据文件移到计算机的其他文件夹中.移动文件的一个原因在于可使备份更容易并且可以让默认的outlook邮件文件不在存在C盘,导致装系统不见或者文件过大而撑死了C盘.例如,如果数据 ...

  4. Redis 数据备份与恢复

    Redis SAVE 命令用于创建当前数据库的备份. 语法 redis Save 命令基本语法如下: redis 127.0.0.1:6379> SAVE 实例 redis 127.0.0.1: ...

  5. 数据库字段类型中char和Varchar区别

    char和varchar区别 char类型:对英文(ASCII)字符占用1个字节,对一个汉字占用2个字节,char存储定长数据很方便,char字段上的索引效率级高,比如定义char(10),那么不论你 ...

  6. 小白日记17:kali渗透测试之缓冲区溢出实例-windows,POP3,SLmail

    缓冲区溢出实例 缓冲区溢出原理:http://www.cnblogs.com/fanzhidongyzby/archive/2013/08/10/3250405.html 空间存储了用户程序的函数栈帧 ...

  7. 杂乱无章之javascript(一)

    1.in 要求第一个(左边的)操作数必须是字符串类型或是可以转化成字符串类型的其他类型,而第二(右边的)操作数必须是数组或对象.只有第一个操作数的值是第二个操作数的属性名,才会返回true,否则返回f ...

  8. C#当前应用程序路径及环境变量

    一.获取当前文件的路径 1. System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName 获取模块的完整路径.可获得当前执行的 ...

  9. git workflows

    https://www.atlassian.com/git/tutorials/comparing-workflows Comparing Workflows The array of possibl ...

  10. hello world of hibernate Annotation

    1:建立所需要的类,如: package com.hibernate.model; import javax.persistence.Entity; import javax.persistence. ...