題目:輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。比如輸入下圖中左邊兒茶搜索樹,則輸出轉換后的排序雙向鏈表。 10 / \ 6 14 / \ / \ 4 8 12 16 4=6=8=10=12=14=16
將二叉搜索樹轉化為有序雙向鏈表,類似於中序遍歷,中序遍歷的結果就是一個排序的數字。因此在程序中以中序遍歷樹,當遍歷左子樹到在葉子結點的時候,開始修改指針。
代碼實例:

#include<iostream> #include<stdlib.h> using namespace std; struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; //創建二叉樹結點 BinaryTreeNode* CreateBinaryTreeNode(int value) { BinaryTreeNode* pNode=new BinaryTreeNode(); pNode->m_nValue=value; pNode->m_pLeft=NULL; pNode->m_pRight=NULL; return pNode; } void ConnectTreeNodes(BinaryTreeNode* pParent,BinaryTreeNode* pLeft,BinaryTreeNode* pRight) { if(pParent!=NULL) { pParent->m_pLeft=pLeft; pParent->m_pRight=pRight; } } void InOrderPrintTree(BinaryTreeNode* pRoot)//中序遍歷 { if(pRoot!=NULL) { if(pRoot->m_pLeft!=NULL)// InOrderPrintTree(pRoot->m_pLeft); cout<<"value of this node is "<<pRoot->m_nValue<<endl; if(pRoot->m_pRight!=NULL) InOrderPrintTree(pRoot->m_pRight); } else { cout<<"this node is null."<<endl; } } void Convert(BinaryTreeNode* pNode,BinaryTreeNode** pLastNodeInList) { if(pNode==NULL) return; BinaryTreeNode* pCurrent=pNode; //左子樹轉換,遍歷到左子樹的葉子結點 if(pCurrent->m_pLeft!=NULL)//遍歷左子樹 Convert(pCurrent->m_pLeft,pLastNodeInList); pCurrent->m_pLeft=*pLastNodeInList; if((*pLastNodeInList)!=NULL) (*pLastNodeInList)->m_pRight=pCurrent; *pLastNodeInList=pCurrent; //右子樹轉換 if(pCurrent->m_pRight!=NULL)//遍歷右子樹 Convert(pCurrent->m_pRight,pLastNodeInList); } BinaryTreeNode* Convert(BinaryTreeNode* pRoot) { BinaryTreeNode* pLastNodeInList=NULL;//指向雙向鏈表的尾結點 Convert(pRoot,&pLastNodeInList);//轉換排序二叉樹為雙向鏈表 //求雙向鏈表的頭結點 BinaryTreeNode* pHeadOfList=pLastNodeInList; while(pHeadOfList!=NULL&&pHeadOfList->m_pLeft!=NULL) pHeadOfList=pHeadOfList->m_pLeft; return pHeadOfList; } //輸出雙向鏈表 void PrintList(BinaryTreeNode* pRoot) { BinaryTreeNode* pNode = pRoot; while(pNode != NULL) { printf("%d\t", pNode->m_nValue); pNode = pNode->m_pRight; } printf("\nPrintList ends.\n"); } void main() { // 10 // / \ // 6 14 // /\ /\ // 4 8 12 16 //創建樹結點 BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10); BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6); BinaryTreeNode* pNode14 = CreateBinaryTreeNode(14); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8); BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12); BinaryTreeNode* pNode16 = CreateBinaryTreeNode(16); //連接樹結點 ConnectTreeNodes(pNode10, pNode6, pNode14); ConnectTreeNodes(pNode6, pNode4, pNode8); ConnectTreeNodes(pNode14, pNode12, pNode16); //PrintTree(pNode10); InOrderPrintTree(pNode10);//中序遍歷 BinaryTreeNode* pHeadOfList=Convert(pNode10);//獲取雙向鏈表頭結點 PrintList(pHeadOfList);//輸出鏈表 system("pause"); }