微软有一道面试题,描述如下:
【题】:将一棵二元查找树转换为一个排序的双向链表。
【要求】:不能创建新的结点,只调整指针的指向。
【思路】:
1、二元查找树的特点:左子树结点的值始终小于根节点的值,右子树结点的值始终大于根节点的值。
2、可以看出二元查找树的中序遍历和排序双向链表的结果非常相似,可以借鉴中序遍历的思想递归处理。
【代码】:
[BinaryFindTreeToDoublyLinkedList.cpp]
#include <stdio.h> #include "BSTree.h" void DoublyLinkedListTraverse(BSTreeNode* head); void treetolist(BSTreeNode* &head, BSTreeNode* &tail, BSTreeNode *root); BSTreeNode* BSTreeToDoublyLinkedList(BSTreeNode* root); void DoublyLinkedListTraverse(BSTreeNode* head); int main(int argc,char** argv) { //输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表 //要求不能创建任何新的节点,只调整指针的指向 printf("二元查找树变为排序的双向链表:\n"); int testdata[] = {6,12,4,16,10,8,14}; //建立一棵二元查找树 BSTreeNode* myTree; myTree = CreateNode(10,NULL,NULL);//root for (int i=0;i<7;i++){ InsertBSTree(testdata[i],myTree); } //中序遍历一棵二元查找树 printf("中序遍历二元查找树:\n"); BSTreeInOrderTraverse(myTree); printf("\n"); //二元查找树变为排序的双向链表,前向遍历双向链表 printf("前向遍历转换后的双向链表:\n"); DoublyLinkedListTraverse(BSTreeToDoublyLinkedList(myTree)); //将该二元查找树变成排序的双向链表 //4<=>6<=>8<=>10<=>12<=>14<=>16 printf("Game Over!Thanks!\n"); getchar(); return 0; } /********************************************************************* BSTreeNode* BSTreeToDoublyLinkedList(BSTreeNode *root): 二元查找树变为排序的双向链表,递归处理 *********************************************************************/ BSTreeNode* BSTreeToDoublyLinkedList(BSTreeNode *root) { BSTreeNode *head, *tail; treetolist(head, tail, root); return head; } void treetolist(BSTreeNode* &head, BSTreeNode* &tail, BSTreeNode *root) { BSTreeNode *lt, *rh; if (root == NULL) { head = NULL, tail = NULL; return; } treetolist(head, lt, root->m_pLeft); treetolist(rh, tail, root->m_pRight); if (lt!=NULL) { lt->m_pRight = root; root->m_pLeft = lt; } else { head = root; } if (rh!=NULL) { root->m_pRight=rh; rh->m_pLeft = root; } else { tail = root; } } void DoublyLinkedListTraverse(BSTreeNode* head) { if (head->m_pRight == NULL){ printf("%d\n",head->m_nValue); return; }else{ printf("%d\t",head->m_nValue); DoublyLinkedListTraverse(head->m_pRight); } }
[BSTree.h]
#include <stdlib.h> #define TRUE 1 #define FALSE 0 typedef int DataType; typedef bool BOOL; /********************************************************************* Binary Search Tree's data structure **********************************************************************/ typedef struct BSTreeNode{ DataType m_nValue; //value of node BSTreeNode *m_pLeft; //left child of node BSTreeNode *m_pRight; //right child of node }BSTreeNode; /********************************************************************* Function Statement **********************************************************************/ BSTreeNode* CreateNode(DataType val,BSTreeNode* lnode,BSTreeNode* rnode); BOOL SearchBSTree(DataType val,BSTreeNode* root); void BSTreePreOrderTraverse(BSTreeNode* root); void BSTreeInOrderTraverse(BSTreeNode* root); void BSTreePostOrderTraverse(BSTreeNode* root); /********************************************************************* create a root BiTree **********************************************************************/ BSTreeNode* CreateNode(DataType val,BSTreeNode* lnode,BSTreeNode* rnode) { BSTreeNode* root; root = (BSTreeNode*)malloc(sizeof(BSTreeNode)); root->m_nValue = val; root->m_pLeft = lnode; root->m_pRight = rnode; return root; } /********************************************************************* search val in BSTree:recursion query **********************************************************************/ BOOL SearchBSTree(DataType val,BSTreeNode* root,BSTreeNode* &p,BSTreeNode* father) { if (root == NULL){ p = father; return FALSE; } if (val == root->m_nValue){ p = root; return TRUE; }else if (val<root->m_nValue){ return SearchBSTree(val,root->m_pLeft,p,root); }else{ return SearchBSTree(val,root->m_pRight,p,root); } } /********************************************************************* insert a new data into BSTree **********************************************************************/ BOOL InsertBSTree(DataType val,BSTreeNode* root) { BSTreeNode* p; p = new BSTreeNode; if (!SearchBSTree(val,root,p,NULL)){ BSTreeNode* newNode; newNode = CreateNode(val,NULL,NULL); if (p==NULL){ root = newNode; }else if (val<p->m_nValue){ p->m_pLeft = newNode; }else{ p->m_pRight= newNode; } return TRUE; }else{ printf("The Data has been existed!\n"); return FALSE; } } /********************************************************************* BSTree traverse:1.inorder traverse recursion **********************************************************************/ void BSTreeInOrderTraverse(BSTreeNode* root) { if (root!=NULL) { BSTreeInOrderTraverse(root->m_pLeft); printf("%d\t",root->m_nValue); BSTreeInOrderTraverse(root->m_pRight); } } /********************************************************************* BSTree traverse:1.preorder traverse recursion **********************************************************************/ void BSTreePreOrderTraverse(BSTreeNode* root) {
if (root!=NULL) { printf("%d\t",root->m_nValue); BSTreePreOrderTraverse(root->m_pLeft); BSTreePreOrderTraverse(root->m_pRight); } } /********************************************************************* BSTree traverse:1.inorder traverse recursion **********************************************************************/ void BSTreePostOrderTraverse(BSTreeNode* root) { if (root!=NULL) { BSTreePostOrderTraverse(root->m_pLeft); BSTreePostOrderTraverse(root->m_pRight); printf("%d\t",root->m_nValue); } }
程序经过VC++6.0测试通过,控制台显示结果如下: