1. 程式人生 > >【劍指offer】二叉搜索樹轉雙向鏈表

【劍指offer】二叉搜索樹轉雙向鏈表

clear user 左右 data- 輸出 bst -m clas 表頭

版權聲明:本文為博主原創文章,未經博主同意不得轉載。

https://blog.csdn.net/mmc_maodun/article/details/26623795

轉載請註明出處:http://blog.csdn.net/ns_code/article/details/26623795

題目描寫敘述:

輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建不論什麽新的結點,僅僅能調整樹中結點指針的指向。

輸入:

輸入可能包括多個測試例子。
對於每一個測試案例,輸入的第一行為一個數n(0<n<1000)。代表測試例子的個數。
接下來的n行。每行為一個二叉搜索樹的先序遍歷序列,當中左右子樹若為空則用0取代。

輸出:

相應每一個測試案例,
輸出將二叉搜索樹轉換成排序的雙向鏈表後,從鏈表頭至鏈表尾的遍歷結果。

例子輸入:
1
2 1 0 0 3 0 0
例子輸出:
1 2 3
? ? 思路:這道題目關鍵在於不能創建新的節點,如不然,我們能夠直接將二叉排序樹中序遍歷保存到一個數組中,而後再建立一個雙性鏈表。將數據保存到雙向鏈表裏。

? ? 這裏不能創建新節點,我們僅僅能改變節點的指向左右子樹的節點,讓其變為指向二叉鏈表中的前後節點,非常明顯這裏相同用的是中序遍歷。因此這道題目依舊是中序遍歷的變種,中序遞歸構造實現就可以,每次遞歸都保存一個指向已構造好的雙向鏈表的尾節點的指針,將其與下一個節點連接起來。

? ? 另外,這道題OJ的輸出格式與前面的不同,輸出例子中又沒有說明,我試了三次才AC。前兩次都是報PE,雙向鏈表的最後一個元素的輸出後面一樣。要有個空格才行。

? ? AC代碼:

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

typedef struct BSTNode
{
	int data;
	struct BSTNode *left;
	struct BSTNode *right;
}BSTNode,*BSTree;

/*
依據題目要求的格式創建二叉排序樹
*/
void CreateBST(BSTree *pRoot)
{
	int data;
	scanf("%d",&data);
	if(data == 0)
		pRoot = NULL;
	else
	{
		*pRoot = (BSTree)malloc(sizeof(BSTNode));
		if(*pRoot == NULL)
			exit(EXIT_FAILURE);
		(*pRoot)->data = data;
		(*pRoot)->left = NULL;
		(*pRoot)->right = NULL;
		CreateBST(&((*pRoot)->left));
		CreateBST(&((*pRoot)->right));
	}
}

/*
採用中序遍歷的方式將二叉樹轉化為雙向鏈表,
*pLas指向雙向鏈表的最後一個節點
*/
void ConvertNode(BSTree pRoot,BSTree *pLast)
{
	if(pRoot == NULL)
		return;
	
	//先轉化左子樹
	if(pRoot->left != NULL)
		ConvertNode(pRoot->left,pLast);

	//將雙向鏈表的最後一個節點與根節點連接在一起
	pRoot->left = *pLast;
	if(*pLast != NULL)
		(*pLast)->right = pRoot;
	*pLast = pRoot;

	//轉換右子樹
	if(pRoot->right != NULL)
		ConvertNode(pRoot->right,pLast);
}

/*
返回雙向鏈表的頭結點
*/
BSTree Convert(BSTree pRoot)
{
	if(pRoot == NULL)
		return NULL;
	if(pRoot->left==NULL && pRoot->right==NULL)
		return pRoot;

	BSTree pLast = NULL;
	ConvertNode(pRoot,&pLast);
	
	//返回頭結點
	BSTree pHead = pLast;
	while(pHead->left != NULL)
		pHead = pHead->left;

	return pHead;
}

int main()
{
	int n;
	while(scanf("%d",&n) != EOF)
	{
		int i;
		for(i=0;i<n;i++)
		{
			BSTree pRoot = NULL;
			CreateBST(&pRoot);
			BSTree pHead = Convert(pRoot);
			while(pHead != NULL)
			{
				printf("%d ",pHead->data);
				pHead = pHead->right;
			}

			printf("\n");
			free(pRoot);
			pRoot = NULL;
		}
	}
	return 0;
}
/**************************************************************????Problem: 1503????User: mmc_maodun????Language: C????Result: Accepted????Time:70 ms????Memory:1704 kb****************************************************************/


【劍指offer】二叉搜索樹轉雙向鏈表