標籤:des style color 使用 os io strong for
-
題目描述:
-
輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向鏈表。要求不能建立任何新的結點,只能調整樹中結點指標的指向。
-
輸入:
-
輸入可能包含多個測試範例。
對於每個測試案例,輸入的第一行為一個數n(0<n<1000),代表測試範例的個數。
接下來的n行,每行為一個二叉搜尋樹的先序遍曆序列,其中左右子樹若為空白則用0代替。
-
輸出:
-
對應每個測試案例,
輸出將二叉搜尋樹轉換成排序的雙向鏈表後,從鏈表頭至鏈表尾的遍曆結果。
-
範例輸入:
-
12 1 0 0 3 0 0
-
範例輸出:
-
1 2 3
思路:1.二叉排序樹的特點就是一個結點的左子樹比它小,右子樹比它大,所以可以根據中序遍曆得到一棵排序的序列。2.若不能建立新結點,那麼我們只能去修改原始二叉樹的指標。這裡我們讓指向左子樹的指標變為鏈表中指向前一個結點的指標,而指向右子樹的指標變為鏈表中指向後一個結點的指標。3.結合上面兩點,很容易寫出一個遞迴的演算法。如下:
代碼:
/*二叉排序樹轉雙向鏈表by Rowandjj2014/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;}
部分函數並沒有使用,可以去掉