码迷,mamicode.com
首页 > 其他好文 > 详细

二叉排序树转化成双向链表

时间:2014-08-06 14:50:01      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:des   style   color   使用   os   io   strong   for   

题目描述:

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数。
接下来的n行,每行为一个二叉搜索树的先序遍历序列,其中左右子树若为空则用0代替。

输出:

对应每个测试案例,
输出将二叉搜索树转换成排序的双向链表后,从链表头至链表尾的遍历结果。

样例输入:
1
2 1 0 0 3 0 0
样例输出:
1 2 3
思路:
1.二叉排序树的特点就是一个结点的左子树比它小,右子树比它大,所以可以根据中序遍历得到一棵排序的序列。
2.若不能创建新结点,那么我们只能去修改原始二叉树的指针。这里我们让指向左子树的指针变为链表中指向前一个结点的指针,而指向右子树的指针变为链表中指向后一个结点的指针。
3.结合上面两点,很容易写出一个递归的算法。如下:

代码:

/*
二叉排序树转双向链表
by Rowandjj
2014/8/6
*/
#include<stdio.h>
#include<stdlib.h>
typedef struct _BNODE_
{
	int data;
	struct _BNODE_ *left;
	struct _BNODE_ *right;
}BNode,*pNode,*pTree;
//---------------------------------------
//其实是一个中序遍历的过程,因为中序遍历二叉排序树可以得到有序序列
void ConvertNode(pTree pRoot,pNode *pTail)
{ 
	if(pRoot == NULL)
	{
		return;
	}
	//左
	pNode pCur = pRoot;
	if(pCur->left != NULL)
	{
		ConvertNode(pCur->left,pTail);
	}
	//根 
	//left指针指向前一个,right指针指向后一个
	pCur->left = *pTail;
	if(*pTail != NULL)
	{
		(*pTail)->right = pCur;
	}
	*pTail = pCur;
	//右
	if(pCur->right != NULL)
	{
		ConvertNode(pCur->right,pTail);
	}
	
}
//将二叉排序树转化为双向链表,返回双向链表头指针
pNode Convert(pTree pRoot)
{
	if(pRoot == NULL)
	{
		return NULL;
	}
	pNode pTail = NULL;
	ConvertNode(pRoot,&pTail);
	pNode pHead = pTail;
	//根据双向链表的尾找到其头指针
	while(pHead != NULL && pHead->left != NULL)
	{
		pHead = pHead->left;
	}
	//返回双向链表头指针
	return pHead;
}
//遍历双向链表
void DisplayLinkedList(pNode pHead)
{
	if(pHead == NULL)
	{
		return;
	}
	pNode pTemp = pHead;
	while(pTemp != NULL)
	{
		printf("%d ",pTemp->data);
		pTemp = pTemp->right;
	}
	printf("\n");
}
//销毁双向链表
void DestroyList(pNode *pHead)
{
	if(*pHead == NULL)
	{
		return;
	}
	pNode p = *pHead,q;
	while(p != NULL)
	{
		q = p->right;
		free(p);
		p = q;
	}
	pHead = NULL;
}
//---------------------------------------
//先序构建二叉树
void CreateTree(pTree *pRoot)
{
	int data;
	scanf("%d",&data);
	if(data == 0)
	{
		return;
	}
	*pRoot = (pNode)malloc(sizeof(BNode));
	if(*pRoot == NULL)
	{
		exit(-1);
	}
	(*pRoot)->data = data;
	(*pRoot)->left = NULL;
	(*pRoot)->right = NULL;
	CreateTree(&(*pRoot)->left);
	CreateTree(&(*pRoot)->right);
}
//先序遍历排序树
void DisplayTree(pTree pRoot)
{
	if(pRoot == NULL)
	{
		return;
	}
	printf("%d ",pRoot->data);
	DisplayTree(pRoot->left);
	DisplayTree(pRoot->right);
}
void DestroyTree(pTree *pRoot)
{
	if(*pRoot == NULL)
	{
		return;
	}
	if((*pRoot)->left != NULL)
	{
		DestroyTree(&(*pRoot)->left);
	}
	if((*pRoot)->right != NULL)
	{
		DestroyTree(&(*pRoot)->right);
	}
	free(*pRoot);
	*pRoot = NULL;
}
int main()
{
	int n;
	while(scanf("%d",&n) != EOF)
	{
		if(n <= 0)
		{
			continue;
		}
		for(int i = 0; i < n; i++)
		{
			pTree pRoot = NULL;
			CreateTree(&pRoot);
			pNode pHead = Convert(pRoot);
			if(pHead != NULL)
			{
				DisplayLinkedList(pHead);
			}
			DestroyList(&pHead);
		}
	}
	return 0;
}

部分函数并没有使用,可以去掉



二叉排序树转化成双向链表,布布扣,bubuko.com

二叉排序树转化成双向链表

标签:des   style   color   使用   os   io   strong   for   

原文地址:http://blog.csdn.net/chdjj/article/details/38400327

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!