数据结构之树和二叉树——树的存储结构和二叉树的构造

一、树的存储结构

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'
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值