王道p150 16.设计一个算法将二叉树的叶结点按从左到右的顺序连成一个单链表,表头指针为 head.二叉树按二叉链表方式存储,链接时用叶结点的右指针域来存放单链表指针。(c语言代码实现)

通常我们所用的先序、中序和后序遍历对于叶结点的访问顺序都是从左到右,这里我们选择中序递归遍历。

设置前驱结点指针 pre,初始为空。第一个叶结点由指针 head 指向,遍历到叶结点时,就将它前驱的 rchild 指针指向它,最后一个叶结点的 rchild 为空。

本题代码如下

tree head =NULL, pre = NULL;
tree inorder(tree* t)
{
	if (*t)
	{
		inorder(&(*t)->lchild);//中序遍历左子树
		if ((*t)->lchild == NULL && (*t)->rchild == NULL)//处理叶结点
		if(pre==NULL)
		{
			head = *t;
			pre = *t;//处理第一个叶结点
		}
		else
		{
			pre->lchild = *t;
			pre = *t;//将叶结点链入链表
		}
		inorder(&(*t)->rchild);//中序遍历右子树
		pre->rchild = NULL;//设置链表尾
	}
	return head;
}

完整测试代码

#include
#include
typedef struct treenode
{
	char data;
	struct treenode* lchild, * rchild;
}treenode,*tree;
void buildtree(tree* t)
{
	char ch;
	ch = getchar();
	if (ch =='#')
		*t = NULL;
	else
	{
		*t = (treenode*)malloc(sizeof(treenode));
		(*t)->data = ch;
		(*t)->lchild = NULL;
		(*t)->rchild = NULL;
		buildtree(&(*t)->lchild);
		buildtree(&(*t)->rchild);
	}
}
tree head =NULL, pre = NULL;
tree inorder(tree* t)
{
	if (*t)
	{
		inorder(&(*t)->lchild);//中序遍历左子树
		if ((*t)->lchild == NULL && (*t)->rchild == NULL)//处理叶结点
		if(pre==NULL)
		{
			head = *t;
			pre = *t;//处理第一个叶结点
		}
		else
		{
			pre->lchild = *t;
			pre = *t;//将叶结点链入链表
		}
		inorder(&(*t)->rchild);//中序遍历右子树
		pre->rchild = NULL;//设置链表尾
	}
	return head;
}
int main()
{
	tree t;
	buildtree(&t);
	head=inorder(&t);
	while (head)
	{
		printf("%c", head->data);
		head = head->lchild;
	}
	return 0;
}

用ABD##E##CF##G##测试

/*                       A

            B                        C

D                   E      F                 G     */

你可能感兴趣的:(树,数据结构,c语言,树,链表)