首页 > 代码库 > 【编程题目】把二元查找树转变成排序的双向链表(树)
【编程题目】把二元查找树转变成排序的双向链表(树)
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 1.把二元查找树转变成排序的双向链表(树) 3 题目: 4 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 5 要求不能创建任何新的结点,只调整指针的指向。 6 10 7 / 8 6 14 9 / \ / 10 4 8 12 16 11 转换成双向链表 12 4=6=8=10=12=14=16。 13 首先我们定义的二元查找树 节点的数据结构如下: 14 struct BSTreeNode 15 { 16 int m_nValue; // value of node 17 BSTreeNode *m_pLeft; // left child of node 18 BSTreeNode *m_pRight; // right child of node 19 }; 20 start time = 14:31 21 end time = 16:04 22 */ 23 #include <iostream> 24 #include <stdlib.h> 25 using namespace std; 26 27 typedef struct BSTreeNode 28 { 29 int m_nValue; // value of node 30 BSTreeNode *m_pLeft; // left child of node 31 BSTreeNode *m_pRight; // right child of node 32 }BSTreeNode; 33 34 int addBSTreeNode(BSTreeNode * &T, int data) //把data加入的以T为根的树中 35 { 36 if(T == NULL) //根节点单独处理 37 { 38 T = (BSTreeNode *)malloc(sizeof(BSTreeNode)); 39 T->m_nValue =http://www.mamicode.com/ data; 40 T->m_pLeft = NULL; 41 T->m_pRight = NULL; 42 } 43 else 44 { 45 BSTreeNode * x = T; 46 BSTreeNode * px = NULL; 47 while(x != NULL) 48 { 49 if(data >= x->m_nValue) 50 { 51 px = x; 52 x = x->m_pRight; 53 } 54 else 55 { 56 px = x; 57 x = x->m_pLeft; 58 } 59 } 60 61 if(data >= px->m_nValue) 62 { 63 px->m_pRight = (BSTreeNode *)malloc(sizeof(BSTreeNode)); 64 px->m_pRight->m_nValue =http://www.mamicode.com/ data; 65 px->m_pRight->m_pLeft = NULL; 66 px->m_pRight->m_pRight = NULL; 67 } 68 else 69 { 70 px->m_pLeft = (BSTreeNode *)malloc(sizeof(BSTreeNode)); 71 px->m_pLeft->m_nValue =http://www.mamicode.com/ data; 72 px->m_pLeft->m_pLeft = NULL; 73 px->m_pLeft->m_pRight = NULL; 74 } 75 } 76 return 1; 77 } 78 79 BSTreeNode * findMin(BSTreeNode * z) 80 { 81 BSTreeNode * x = z; 82 while(x->m_pLeft != NULL) 83 { 84 x = x->m_pLeft; 85 } 86 return x; 87 } 88 89 BSTreeNode * findMax(BSTreeNode * z) 90 { 91 BSTreeNode * x = z; 92 while(x->m_pRight != NULL) 93 { 94 x = x->m_pRight; 95 } 96 return x; 97 } 98 99 BSTreeNode * findparent(BSTreeNode * T,BSTreeNode * z)100 {101 BSTreeNode * x = T;102 BSTreeNode * px = NULL;103 while(x != NULL)104 {105 if(z->m_nValue > x->m_nValue)106 {107 px = x;108 x = x->m_pRight;109 }110 else if(z->m_nValue < x->m_nValue)111 {112 px = x;113 x = x->m_pLeft;114 }115 else116 {117 if(z == x) //对数值相同的情况做判断 118 {119 return px;120 }121 else122 {123 px = x;124 x = x->m_pRight;125 }126 }127 }128 return NULL;129 }130 131 BSTreeNode * BSTreefindSuccessor(BSTreeNode * T, BSTreeNode * z) //找二元查找树某个节点的后继132 {133 if(z->m_pRight != NULL)134 {135 return findMin(z->m_pRight);136 }137 else138 {139 BSTreeNode * y = findparent(T, z);140 while(y != NULL && z == y->m_pRight)141 {142 z = y;143 y = findparent(T, z);144 }145 return y;146 }147 }148 149 BSTreeNode * BSTree2OrderedList(BSTreeNode * T) //把二元查找树转换为排序的双向链表150 {151 BSTreeNode * start = findMin(T);152 BSTreeNode * end = findMax(T);153 BSTreeNode * x = start;154 BSTreeNode * root = T;155 while(x != NULL)156 {157 BSTreeNode * xs = BSTreefindSuccessor(root, x);158 if(xs == root && root != NULL) //当root 左右子树的指向改变的时候 要更新找后继的树根 否则根的右子树变化了 用找后继会出错159 {160 root = root->m_pRight;161 }162 if(xs != NULL)163 {164 x->m_pRight = xs; //向右指向下一个比它大的值165 xs->m_pLeft = x; //向左指向下一个比它小的值166 }167 x = xs;168 }169 return start;170 }171 172 173 int main()174 {175 BSTreeNode * T = NULL;176 addBSTreeNode(T, 10);177 addBSTreeNode(T, 6);178 addBSTreeNode(T, 6);179 addBSTreeNode(T, 4);180 addBSTreeNode(T, 8);181 addBSTreeNode(T, 12);182 addBSTreeNode(T, 16);183 184 BSTreeNode * ans = BSTree2OrderedList(T);185 186 return 0;187 188 }
之后上网看看别人的 结果人家一个中序遍历就搞定了啊!
来源:http://blog.csdn.net/wcyoot/article/details/6428297
1 template<typename T> 2 struct TreeNode 3 { 4 T data; 5 TreeNode* pLChild; 6 TreeNode* pRChild; 7 }; 8 9 // 要求两个输出参数要初始化为NULL10 template<typename T>11 void ConvertBSTree2List(TreeNode<T>* pTreeRoot/*树的根节点*/, TreeNode<T>*& pListHead/*双向链表的头指针*/, TreeNode<T>*& pListLast/*双向链表的尾指针*/)12 {13 if(pTreeRoot == NULL)14 {15 return;16 }17 18 // 中序遍历左子树19 ConvertBSTree2List(pTreeRoot->pLChild, pListHead, pListLast);20 21 // 处理当前节点,把节点链到双向链表尾部22 23 // 修改当前节点左指针,指向双向链表尾部24 pTreeRoot->pLChild = pListLast;25 if(pListLast) // 非第一个节点26 {27 pListLast->pRChild = pTreeRoot;28 }29 else // 第一个节点30 {31 pListHead = pTreeRoot; 32 }33 34 pListLast = pTreeRoot;35 36 // 中序遍历右子树37 ConvertBSTree2List(pTreeRoot->pRChild, pListHead, pListLast);38 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。