/**
* 题目:
* 1.把二元查找树转变成排序的双向链表(树)
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ /
6 14
/ / / /
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
*/
/*
* 想法:如果采用中序遍历,那么就是从小到大排序的输出,但是这里要求不能创建任何新的节点,只能调整指针的指向
* 每遍历一个节点,实际上要做两件事:①让前一个节点的右指针指向当前节点 ②让当前节点的左指针指向前一个节点
*
* 那么势必要记录前一个节点,而且还需要处理头指针的问题
*
* 骨架为中序遍历,但是在之前输出中序遍历值的位置,并不是输出值,而是做上面①和②两点的操作
*
*/
#include <iostream>
#include <stack>
using namespace std;
/*
* 类的成员变量以m_开头
*/
struct BSTreeNode {
int m_iValue;
BSTreeNode* m_pLeft;
BSTreeNode* m_pRight;
BSTreeNode(int key) :
m_iValue(key), m_pLeft(), m_pRight() {
}
};
struct BSTree {
BSTreeNode* root;
BSTree() :
root(NULL) { //初始的时候给一个空指针给root,因为是空树
}
void BSTree_Insert(int key); //申明
void BSTree_Travel_1(BSTreeNode* t);
void BSTree_Travel_2(BSTreeNode* t);
};
/*
* 实现插入函数
*/
void BSTree::BSTree_Insert(int key) {
BSTreeNode* x = this->root;
BSTreeNode* y = NULL;
BSTreeNode* n = new BSTreeNode(key);
while (x != NULL) {
y = x;
if (key < x->m_iValue) {
x = x->m_pLeft;
} else {
x = x->m_pRight;
}
}
if (y == NULL) {
this->root = n;
} else if (key < y->m_iValue) {
y->m_pLeft = n;
} else {
y->m_pRight = n;
}
}
//递归中序遍历
void BSTree::BSTree_Travel_1(BSTreeNode* t) {
if (t != NULL) {
BSTree_Travel_1(t->m_pLeft);
cout << t->m_iValue << ' ';
BSTree_Travel_1(t->m_pRight);
}
}
//非递归中序遍历
void BSTree::BSTree_Travel_2(BSTreeNode* t) {
stack<BSTreeNode*> s;
while (t != NULL || !s.empty()) {
// if (t != NULL) {
while (t != NULL) { //这里要用while,因为要一口气将左边的路径上的节点全部入栈
s.push(t);
t = t->m_pLeft;
}
if (!s.empty()) {
t = s.top();
cout << t->m_iValue << ' ';
s.pop();
t = t->m_pRight;
}
}
}
typedef struct BSTreeNode pDoubleList;
pDoubleList* pHead = NULL;
pDoubleList* pListTmp = NULL;
/*
* 转换过程
*/
void conversion(BSTreeNode*& pCurrent) {
pCurrent->m_pLeft = pListTmp; //指向前
if (pCurrent->m_pLeft != NULL) {
pCurrent->m_pLeft->m_pRight = pCurrent; //前一个的指向后,也就是指向当前
} else {
pHead = pCurrent;
}
pListTmp = pCurrent; //决定下一个的指向前目标
}
/*
* 将二叉搜索树转换为双向链表
*/
pDoubleList* convert_To_Double_List(BSTreeNode* pCurrent) {
if (pCurrent == NULL) {
return NULL;
}
if (pCurrent->m_pLeft != NULL) {
convert_To_Double_List(pCurrent->m_pLeft);
}
conversion(pCurrent);
if (pCurrent->m_pRight != NULL) {
convert_To_Double_List(pCurrent->m_pRight);
}
return pHead;
}
/*
* 简洁版
*/
void change(BSTreeNode *p, BSTreeNode *&last) //中序遍历
{
if (!p) //为空则返回
return;
change(p->m_pLeft, last); //处理左
if (last) //处理当前
last->m_pRight = p;
p->m_pLeft = last;
last = p;
change(p->m_pRight, last); //处理右
}
int main() {
pHead = NULL;
pListTmp = NULL;
BSTree* bst = new BSTree();
bst->BSTree_Insert(5);
bst->BSTree_Insert(8);
bst->BSTree_Insert(1);
bst->BSTree_Insert(99);
bst->BSTree_Insert(-2);
bst->BSTree_Travel_1(bst->root);
cout << endl;
bst->BSTree_Travel_2(bst->root);
cout << endl;
pHead = convert_To_Double_List(bst->root);
while (pHead != NULL) {
cout << pHead->m_iValue << ' ';
pHead = pHead->m_pRight;
}
cout << endl;
return 0;
}
【微软100题】001把二元查找树转变成排序的双向链表(树)
最新推荐文章于 2021-10-14 20:18:03 发布