1.把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。 10 / 6 14 / / 4 8 12 16 转换成双向链表 4=6=8=10=12=14=16。 首先我们定义的二元查找树 节点的数据结构如下: struct BSTreeNode { int m_nValue; // value of node BSTreeNode *m_pLeft; // left child of node BSTreeNode *m_pRight; // right child of node };
解决方法:
// 1:构造二叉查找树; // 2:中序遍历二叉查找树,因此结点按从小到大顺序访问,假设之前访问过 //的结点已经调整为一个双向链表,那么只需要将当前结点连接至双向链表的 //最后一个结点即可,访问完后,双向链表也就调整完了 #include<iostream> using namespace std; struct BSTreeNode{ int m_nValue;//value of node BSTreeNode *m_pLeft;//left child node BSTreeNode *m_pRight;//right child node }; //指向循环队列头结点 BSTreeNode *pHead=NULL; //指向前一个结点 BSTreeNode *pIndex=NULL; //建立二叉排序树 void addBSTreeNode(BSTreeNode *&pCurrent,int value){ //如果当前结点为空,直接插入,如果比当前结点大,插入当前结 //点的右结点,如果下,插入左结点。如果相等,默认忽略那个值 //第一个参数的&非常重要。否则需要手动遍历树来找到结点的位置 if(pCurrent==NULL){ BSTreeNode *pBSTree=new BSTreeNode(); pBSTree->m_nValue=value; pBSTree->m_pLeft=NULL; pBSTree->m_pRight=NULL; pCurrent=pBSTree; }else if(pCurrent->m_nValue>value){ addBSTreeNode(pCurrent->m_pLeft,value); }else if(pCurrent->m_nValue<value){ addBSTreeNode(pCurrent->m_pRight,value); }else{ cout<<"node repeated,default ignore"<<endl; } } //将结点转换成双向链表的结点,调整结点指针 //目的,将左结点变成前一个结点,当前结点变成最后的结点 void convertToDoubleList(BSTreeNode *pCurrent){ //将左结点变为前一个结点。 pCurrent->m_pLeft=pIndex; if(pIndex==NULL) pHead=pCurrent;//前一个结点不存在,说明当前为第一个结点 else pIndex->m_pRight=pCurrent; //目的达到后,要将前一个结点设为双向链表的最后一个结点 pIndex=pCurrent; cout<<pCurrent->m_nValue<<" "; } //中序遍历二叉树,调整结点指针.唯一不同的是,遍历结点时要将结点转换成双向链表 void inOrderBSTree(BSTreeNode *pBSTree){ if(pBSTree ==NULL){ return; } if(pBSTree->m_pLeft!=NULL) inOrderBSTree(pBSTree->m_pLeft); convertToDoubleList(pBSTree); if(pBSTree->m_pRight!=NULL) inOrderBSTree(pBSTree->m_pRight); } int main(){ BSTreeNode *root=NULL; addBSTreeNode(root,10); addBSTreeNode(root,6); addBSTreeNode(root,14); addBSTreeNode(root,4); addBSTreeNode(root,8); addBSTreeNode(root,12); addBSTreeNode(root,16); inOrderBSTree(root); return 0; }