一个小算法题目
/* 根据数组创建二元查找树,再把二元查找树转变成排序的双向链表 要求不能创建任何新的结点,只调整指针的指向。 10 / \ 6 14 / \ / \ 4 8 12 16 转换成双向链表:4=6=8=10=12=14=16。 */
第一版程序写出来如下:
struct BSTreeNode *bstree2dlist(struct BSTreeNode *bt)
{
struct BSTreeNode *anchor = NULL;
struct BSTreeNode *ret = bt;
if(bt->m_pLeft != NULL) {
if(bt->m_pLeft->m_pRight != NULL) {
anchor = bt;
anchor->m_pLeft = _max(bstree2dlist(bt->m_pLeft));
anchor->m_pLeft->m_pRight = anchor;
ret = anchor;
} else {
bt->m_pLeft = _max(bstree2dlist(bt->m_pLeft));
bt->m_pLeft->m_pRight = bt;
ret = bt;
}
}
if(bt->m_pRight != NULL) {
if(bt->m_pRight->m_pLeft != NULL) {
anchor = bt;
anchor->m_pRight = _min(bstree2dlist(bt->m_pRight));
anchor->m_pRight->m_pLeft = anchor;
ret = anchor;
} else {
bt->m_pRight = _min(bstree2dlist(bt->m_pRight));
bt->m_pRight->m_pLeft = bt;
ret = bt->m_pRight;
}
}
return ret;
}
其中_max和_min分别找到链表中的最大(最右)和最小(最左)元素。
第二版:
struct BSTreeNode *bstree2dlist(struct BSTreeNode *bt)
{
if(bt->m_pLeft != NULL) {
bt->m_pLeft = bstree2dlist(bt->m_pLeft);
while(bt->m_pLeft->m_pRight != NULL) bt->m_pLeft = bt->m_pLeft->m_pRight;
bt->m_pLeft->m_pRight = bt;
}
if(bt->m_pRight != NULL) {
bt->m_pRight = bstree2dlist(bt->m_pRight);
while(bt->m_pRight->m_pLeft != NULL) bt->m_pRight = bt->m_pRight->m_pLeft;
bt->m_pRight->m_pLeft = bt;
}
return bt;
}
把anchor这个“想象中”特殊处理的结点去掉了,思维惯性影响,原来是背负着抱负写上去的。还把_max、_min方法直接放函数里面。
网上的版本:
void bstree2dlist(struct BSTreeNode *root)
{
static struct BSTreeNode *last = NULL;
if(root)
{
bstree2dlist(root->m_pLeft);
if(last)
{
last->m_pRight = root;
root->m_pLeft = last;
}
last = root;
bstree2dlist(root->m_pRight);
}
}
想了一些:
- 始终未掌握递归程序的写法,脑细胞不够用,一旦涉及嵌套,像看《盗梦空间》一样,晕头转向。
- 背负着心智抱负去做东西,自己的行为及受到了限制;把一些样板的东西放在那里,妄想通过它来找到某种捷径;最终,发现正是它在拖后腿。
- 凡事总是从薄->厚->“薄”。前者的薄是无知,后者的薄是深刻了解一件事物后剩下的骨干,排除自己烂熟的东西之后所“新”认识到的东西。
- K.C.K.T
- 效率!

浙公网安备 33010602011771号