学习研究v_JULY_v整理的微软数据结构和算法面试题

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.双链表:DLinkList类型定义:

typedef struct DNode

{

ElemType data;        /*数据元素*/

struct DNode *prior;/*指向前驱结点*/

struct DNode *next  /*指向后继结点*/

}DLinkList;                        /*定义双链表节点类型*/

3.二元查找树的结构如题目当中的二叉链式存储结构lchild,data,rchild.

4.BSTreeNode *&pCurrent   从右至左的优先级,即:&pCurrent代表引用,类型是指针BSTreeNode *

5.双链表图解:


解答:

// BSTreeNode.cpp : 将二元查找树转变成双链表。
//

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;


typedef struct BSTreeNode
{
int m_data;                 /* 数据元素*/
BSTreeNode *m_lchild;       /* 指向左孩子结点 */
BSTreeNode *m_rchild;       /* 指向右孩子结点 */
}DoubleLink;                    /* 二元查找树结点定义 */


DoubleLink *pHead;              /* 指向双链表的头结点 */
DoubleLink *pListIndex;        /* 指向双链表的最后一个结点 */


/* 调整结点指针 */
void convertoDoubleLinkList(BSTreeNode* pCurrent);


/* 创建二元查找树 */
void addBSTreeNode(BSTreeNode* &pCurrent, int data)
{
if(NULL == pCurrent)
{
BSTreeNode *pBSTree = new BSTreeNode();
pBSTree->m_lchild = NULL;
pBSTree->m_rchild = NULL;
pBSTree->m_data = data;
pCurrent = pBSTree;
}
else
{
if ((pCurrent->m_data) > data)
{
addBSTreeNode(pCurrent->m_lchild,data);

else if((pCurrent->m_data) < data)
{
addBSTreeNode(pCurrent->m_rchild, data);
}
else
{
/* 重复添加相同的元素 */
cout<<"node repeated"<<endl;
}
}
}


/* 遍历二元查找树 数据结构算法书中的中序遍历 */
void ergodicBSTree(BSTreeNode *pCurrent)
{
if(NULL == pCurrent)
{
return;
}
if(NULL != pCurrent->m_lchild)
{
ergodicBSTree(pCurrent->m_lchild);
}
/* 节点接到链表尾部 */
convertoDoubleLinkList(pCurrent);
/* 右子树不为空 */
if(NULL != pCurrent->m_rchild)
{
ergodicBSTree(pCurrent->m_rchild);
}
}


/* 二叉树转换成List */
void convertoDoubleLinkList(BSTreeNode* pCurrent)
{
pCurrent->m_lchild = pListIndex;    /* 当前结点的左指针指向双链表的最后一个结点,其余的指向前一个结点 */
if (NULL == pListIndex)             /* 如果最后一个结点不存在,说明双链表为空,则将此结点作为双链表的头结点*/  
{
pHead = pCurrent;
}
else                               /* 使双链表的最后一个结点的右指针指向首结点其他情况时指向当前结点的下一个结点 */
{
pListIndex->m_rchild = pCurrent;
}
pListIndex = pCurrent;             /* 将当前结点作为最后一个结点 */
cout<<pCurrent->m_data<<endl;      /* 输出 */
}


int _tmain(int argc, _TCHAR* argv[])
{
BSTreeNode * pRoot = NULL;
pListIndex = NULL;
pHead = NULL;
addBSTreeNode(pRoot, 10);
addBSTreeNode(pRoot, 4);
addBSTreeNode(pRoot, 6);
addBSTreeNode(pRoot, 8);
addBSTreeNode(pRoot, 12);
addBSTreeNode(pRoot, 14);
addBSTreeNode(pRoot, 15);
addBSTreeNode(pRoot, 16);
ergodicBSTree(pRoot);
return 0;
}

上述问题的研究参看了很多人的作品,如果有任何问题和不对的地方,请大家见谅,给予支持,并指正错误,谢谢。

另:相关的参考博客;http://blog.csdn.net/yysdsyl/article/details/1841632

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值