一、树的存储结构
1.顺序存储
typedef int datatype;
typedef struct node{
datatype data; //结点的数据
int parent; //存储其双亲结点下标
}Pnode;
2.链式存储
(1)孩子表示法 :
如图:
假设一棵树的度为3,那么其存储结构可以表示为:
typedef char datatype;
typedef struct node{
datatype data;
struct node *lchild;
struct node *mchild;
struct node *rchild;
}CFnode;
若是非固定度数的树,就可以用二级指针表示:
typedef char datatype;
typedef struct node{
datatype data;
int degree; //用于存储树的度数
struct node **child;//动态设置孩子结点指针的数组
}CUFnode;
child = (CUFnode **)malloc(degree * sizeof(CUFnode *));
(2)孩子——兄弟表示法:
构造如图:
算法如下:
typedef int datatype;
typedef struct node{
datatype data;
struct node *lchild; //指向最左边孩子
struct node *Sibling; //指向右边第一个兄弟结点
}CSnode;
3.数组链式存储法
算法实现如下:
typedef int datatype;
typedef struct Snode{
datatype data; //结点的数据类型
struct Snode *next; //指向下一个结点
}Siblingnode;
typedef struct node{
datatype data;
int parent;
Sibling *head; //指向孩子结点单链表的头结点
}Pcnode;
void main(){
BTNode * root4 = CreateTree();
//输入ABD###CE#G##F##
}
二、二叉树的构造
1.二叉树的数据类型定义:
二叉树:即所有结点的度 ≤ 2 的树
typedef char datatype;
typedef struct BTNode{
datatype data;
struct BTNode *rchild, *lchild;
}BTNode;
2.二叉树的构建:
例如构造如下二叉树:
(1)递归法
BTNode* CreateTree(){
//按先序遍历的输出次序输入一个字符串,
//其中每个字符代表二叉树中一个结点的值,
//用’#’字符表示空结点。
//试根据此先序遍历的字符次序一次性构造出链式二叉树。
char ch;
BTNode *T;
ch = getchar();
if(ch == '#') T = NULL;
else{
T = (BTNode *)malloc(sizeof(BTNode));
if(!T) printf("申请空间失败\n");
else{
T->data = ch;
T->lchild = CreateTree();
T->rchild = CreateTree();
}
}
return T;
}
#####(2)直接构造:
//先创建根节点:
BTNode *CreateRoot(char c){
BTNode *tmp = (BTNode *)malloc(sizeof(BTNode));
//别忘了判断malloc不成功的情况
if(!tmp){printf("申请空间失败,无法创建根结点\n");}
else{
tmp->data = c;
tmp->rchild = NULL;
tmp->lchild = NULL;
}
return tmp;
}
//插入左孩子结点:
BTNode *InsertLeftNode(BTNode *curNode, char c){
BTNode *tmp = (BTNode *)malloc(sizeof(BTNode));//先申请一个结点的空间
if(!tmp) printf("申请空间失败,无法创建根结点\n");//这个if的常规套路还是要写一写
else{
tmp->data = c; //给元素赋值
tmp->lchild = curNode->lchild; //在原来的 双亲——孩子结点 之间插入,把原来根节点所连接的左孩子变成tmp的左孩子,若原先根节点的lchild为NULL,则现在tmp的lchild为NULL
tmp->rchild = NULL;//右孩子为空
curNode->lchild = tmp;//最后让自己成为根结点的左孩子
}
return tmp;
}
//插入右孩子结点:
BTNode *InsertRightNode(BTNode *curNode, char c){
//基本思路:同上
BTNode *tmp = (BTNode *)malloc(sizeof(BTNode));
if(!tmp) printf("申请空间失败,无法创建根结点\n");
else{
tmp->data = c;
tmp->rchild = curNode->rchild;
tmp->lchild = NULL;
curNode->rchild = tmp;
}
return tmp;
}
void main(){
BTNode *root, *curNode;
root = curNode = CreateRoot('A');
InsertLeftNode(curNode, 'D');//先生成A的左孩子结点D;
InsertLeftNode(curNode, 'B');//在'A'和'D'之间插入'B';
InsertRightNode(curNode, 'F');//生成A的右孩子结点F;
curNode = InsertRightNode(curNode, 'C');//在'A'与'F'之间插入'C',再把'C'变为当前的根节点;
curNode = InsertLeftNode(curNode, 'E');//插入'E',变成'C'的左孩子结点;
//再把当前根节点变为'E'
InsertRightNode(curNode, 'G');//生成E的右孩子结点'G'
}