链表节点面试100题系列之1将查找二叉树转换成有序的双向链表

在写这篇文章之前,xxx已经写过了几篇关于改链表节点主题的文章,想要了解的朋友可以去翻一下之前的文章

    1、将二元找查树转化成序排的双向链表,标题起源:

    http://blog.csdn.net/v_JULY_v/article/details/6057286

    10

    / \

    6 14

    / \ / \

    4 8 12 16 => 4<=>6<=>8<=>10<=>12<=>16

    要求:不能创立节点,只变改针指的指向

    法方:其实就是树的中序遍历。用递归的法方build树,然后再将遍历到的节点一个一个的加到链表中去。

#include<stdio.h>

#include<string.h>

struct NODE

{

	int data;

	NODE *Left;

	NODE *Right;

};

const int N = 20;

NODE node[N];

int top;

void Add(NODE *root, int v)

{

	if(!root)

		return;

	if(root->data < v)

	{

		if(root->Right)

			Add(root->Right, v);

		else

		{

			root->Right = &node[++top];

			node[top].data = v;

		}

	}

	else if(root->data > v)

	{

		if(root->Left)

			Add(root->Left, v);

		else

		{

			root->Left = &node[++top];

			node[top].data = v;

		}

	}

	else

		printf("重复参加节点%d\n", v);	

}

//转化后之链表是降序排列的

NODE *TransTreeToLink(NODE *root)

{

	if(!root)

		return NULL;

	NODE *stack[N];

	int top = -1;

	NODE *p = root;

	NODE *head = NULL;

	while(p != NULL || top > -1)

	{

		while(p != NULL)

		{

			stack[++top] = p;

			p = p->Left;

		}

		if(top > -1)

		{

			p = stack[top]->Right;

			if(!head)

				head = stack[top];

			else

			{

				//现实与链表的链接,先连,后断

				stack[top]->Left = head;

				head->Right = stack[top];

				head = stack[top];

			}

			--top;		

		}

	}

	return head;

}

//打印链表

void Print(NODE *head)

{

	if(!head)

		return;

	NODE *p;

	p = head;

	while(p != NULL)

	{

		printf("%d ",p->data);

		p = p->Left;

	}

	printf("\n");

}



int main()

{

	int n,i,v;

	NODE *head;

	while(scanf("%d", &n) != EOF)

	{

		memset(node, 0, sizeof(node));

		top = 0;

		scanf("%d", &v);

		node[0].data = v;

		for(i = 1; i < n; ++i)

		{

			scanf("%d", &v);

			Add(&node[0], v);

		}

		head = TransTreeToLink(&node[0]);

		Print(head);

	}

}

    PS:附上前以写得很挫的码代:两个关于NODE的定义都是一样的。

    每日一道理
漫漫人生路,谁都难免会遭遇各种失意或厄运。在凄风苦雨 惨雾愁云的考验面前,一个强者,是不会向命运低头的。风再冷,不会永远不息;雾再浓,不会经久不散。风息雾散,仍是阳光灿烂。
/*****************************************************************************

*1、将二元找查树转化成序排的双向链表

*			  10

*			 /  \

*			6	 4

*		   / \  / \

*		  4  8 12 16  => 4<=>6<=>8<=>10<=>12<=>16

*要求:不能创立节点,只变改针指的指向

*法方:递归和栈。其实就是树的中序遍历。

******************************************************************************/

//将节点参加树间中

bool AddNodeToTree(TREENODE* &pRoot, int Value)

{

	if(NULL == pRoot)

	{

		TREENODE *pTemp;

		pTemp = (TREENODE *)malloc(sizeof(TREENODE));

		if(NULL == pTemp)

		{

			printf("参加节点%d失败。", Value);

		}

		pTemp->Data = Value;

		pTemp->left = NULL;

		pTemp->right = NULL;

		pRoot = pTemp;

		return true;

	}

	if(Value < pRoot->Data)

	{

		AddNodeToTree(pRoot->left, Value);	

	}

	else if(Value > pRoot->Data)

	{	

		AddNodeToTree(pRoot->right, Value);

	}

	else

	{

		printf("重复参加节点%d\n", Value);

		return false;

	}

}

//将节点转化成有序链表

TREENODE *TransTreeToLink(TREENODE *pRoot)

{

	if(!pRoot)

	{

		return NULL;

	}



	TREENODE *pTemp;

	//录记链表中的头结点

	TREENODE *pList = NULL;

	TREENODE *Stack[MAX_SIZE];

	int top = -1;

	

	//将根节点的左、右及自己入栈

	if(pRoot->right != NULL)

	{

		Stack[++top] = pRoot->right;

	}

	Stack[++top] = pRoot;

	if(pRoot->left != NULL)

	{

		Stack[++top] = pRoot->left;

	}



	while(top > -1)

	{

		pTemp = Stack[top];

		--top;

		if(NULL == pTemp->left && NULL == pTemp->right)

		{

			//如果是第一个进入链表的节点

			pTemp->left = pList;

			if(pList != NULL)

			{

				pList->right = pTemp;

			}



			//判断是不是栈中只有最后一个节点未入链表

			if(top >= 0)

			{

				//链表和树之间的连接

				pTemp->right = Stack[top];

				Stack[top]->left = pTemp;

				//更新链头表节点

				pList = Stack[top];

				--top;

			}

			else

			{

				pList = pTemp;

			}

		}//end if(NULL == pTemp->left && NULL == pTemp->right)

		//如果不是第一个入链表的节点

		else

		{

			if(pTemp->right != NULL)

			{

				Stack[++top] = pTemp->right;

			}

			Stack[++top] = pTemp;

			if(pTemp->left != NULL)

			{

				Stack[++top] = pTemp->left;

			}	

		}//end else

	}//end while(top > -1)

	return pList;

}

//打印链表

void Print(TREENODE *pList)

{

	if(pList ==NULL)

	{

		return;

	}

	TREENODE *pTemp;

	pTemp = pList;

	while(pTemp != NULL)

	{

		printf("%d\t", pTemp->Data);

		pTemp = pTemp->left;

	}

}

//销毁链表

void Destroy(TREENODE *pList)

{

	if(pList == NULL)

	{

		return;

	}

	TREENODE *pTemp;

	

	while(pList != NULL)

	{

		pTemp = pList;



		pList = pList->left;

		free(pTemp);

		pTemp = NULL;		

	}

}

文章结束给大家分享下程序员的一些笑话语录: 《诺基亚投资手机浏览器UCWEB,资金不详或控股》杯具了,好不容易养大的闺女嫁外国。(心疼是你养的吗?中国创业型公司创业初期哪个从国有银行贷到过钱?)

你可能感兴趣的:(双向链表)