天天算法03——二元查找树转变成排序的双向链表

题目:

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

         10
         / \
        6  14
       / \ / \
      4 8 12 16

转换成双向链表
4=6=8=10=12=14=16。

解答:

二元查找树: 它首先要是一棵二元树,在这基础上它或者是一棵空树;或者是具有下列性质的二元树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3)左、右子树也分别为二元查找树

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

struct BSTreeNode{
	int m_nValue;
	struct BSTreeNode * m_pLeft;
	struct BSTreeNode * m_pRight;
};

enum ChildPosition{
	Left,
	Right
};

struct BSTreeNode * creat_tree_root(int root_value)
{
	struct BSTreeNode *root = malloc(sizeof(struct BSTreeNode));

	if(root){
		root->m_nValue = root_value;
		root->m_pLeft = NULL;
		root->m_pRight = NULL;
	}

	return root;
}

struct BSTreeNode *add_child_to_tree(struct BSTreeNode *parent,
									enum ChildPosition pos,
									int child_value)
{
	struct BSTreeNode *retVal = NULL;
	if(parent){
		struct BSTreeNode *child = malloc(sizeof(struct BSTreeNode));
		if(child){
			child->m_nValue = child_value;
			child->m_pLeft = NULL;
			child->m_pRight = NULL;

			if(pos == Left)
				parent->m_pLeft = child;
			else
				parent->m_pRight = child;
			retVal = child;
		}
	}

	return retVal;
}

struct BSTreeNode * creat_example_tree()
{
	struct BSTreeNode * root = NULL;
	struct BSTreeNode * lChild, * rChild; 
	if((root=creat_tree_root(10)) == NULL)
		printf("creat tree root fill!\n");
	
	lChild = add_child_to_tree(root, Left, 6);
	rChild = add_child_to_tree(root, Right, 14);
	add_child_to_tree(lChild, Left, 4);
	add_child_to_tree(lChild, Right, 8);
	add_child_to_tree(rChild, Left, 12);
	add_child_to_tree(rChild, Right, 16);

	return root;
}

void change_ptr(struct BSTreeNode *root)
{
	static struct BSTreeNode *last = NULL;
	if(root){
		change_ptr(root->m_pLeft);
		if(last){
			last->m_pRight = root;
			root->m_pLeft = last;
		}
		last = root;
		change_ptr(root->m_pRight);
	}
}

struct BSTreeNode *find_head(struct BSTreeNode *curr)
{
	struct BSTreeNode *head = NULL;
	while(curr){
		head =  curr;
		curr = curr->m_pLeft;
	}

	return head;
}

struct BSTreeNode * to_link_list(struct BSTreeNode *root)
{
	change_ptr(root);
	return find_head(root);
}

int main()
{
	struct BSTreeNode *root = creat_example_tree();
	struct BSTreeNode *head = to_link_list(root);

	struct BSTreeNode *tail = NULL;
	while(head){
		printf("%d\n", head->m_nValue);
		tail = head;
		head = head->m_pRight;
	}

	printf("reverse iterate:\n");

	while(tail){
		printf("%d\n",tail->m_nValue);
		tail = tail->m_pLeft;
	}
	return 0;
}

参考资料:

http://baike.baidu.com/view/6444378.htm

http://www.cnblogs.com/codingmylife/archive/2011/02/25/1964654.html

posted on 2011-10-29 20:07  comeby  阅读(246)  评论(0编辑  收藏  举报