【问题描述】
编写程序在不增加结点的情况下,将二叉排序树转换成有序双向链表(如下图)。
链表创建结束后,按照从前往后的顺序输出链表中结点的内容。
【输入输出】
【输入形式】
第一行输入数字n,第二行输入n个整数。
【输出形式】
按照从后往前的顺序输出链表中的结点内容。
【样例输入】
6 63 55 90 58 98 70
【样例输出】
Convert binary sort tree into linked list...
55 58 63 70 90 98
【代码】
多加了个逆序输出链表内容……
#include<iostream>
using namespace std;
const int MAX = 1000;
struct BiNode {int data;BiNode* lchild, * rchild;
};class BiSortTree {
private:BiNode* root; //指向根结点的头指针BiNode* rear; //指向尾结点的指针//BiNode *pre; //---指向当前访问的结点的前序节点
public:BiSortTree(int array[], int arrayLength); //构造函数,建立一棵二叉树~BiSortTree(); //---void convertBiToLink(); //---二叉排序树转换成双向链表void DisplayLink(); //---显示双向链表void ReverseDisplayLink(); //---逆序显示void release(BiNode* bt);
private:void insertBST(BiNode*& bt, BiNode *key);void convert(BiNode* bt); //---二叉排序树转换成双向链表的递归程序
};
BiSortTree::BiSortTree(int array[], int arrayLength)
{root = NULL; for (int i = 0; i < arrayLength; i++){BiNode* p = new BiNode;p->lchild = p->rchild = NULL;p->data = array[i];insertBST(root, p);}
}
BiSortTree::~BiSortTree()
{release(root);
}
void BiSortTree::release(BiNode* bt)
{if (bt != NULL){release(bt->lchild);release(bt->rchild);delete bt;bt = NULL;}
}
// 插入节点
void BiSortTree::insertBST(BiNode*& bt, BiNode *key)
{if (bt == NULL){bt = new BiNode;bt->data = key->data;bt->lchild = NULL;bt->rchild = NULL;}else{if (key->data < bt->data)insertBST(bt->lchild, key);else if (key->data > bt->data)insertBST(bt->rchild, key);}
}/*二叉排序树转换成双向链表二叉排序树的递归定义是:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉排序树;实现思路:
1.二叉排序树的特点就是一个结点的左子树比它小,右子树比它大,所以可以根据中序遍历得到一棵排序的序列。
2.由于不能创建新结点,那么我们只能去修改原始二叉树的指针。这里我们让指向左子树的指针变为链表中指向前序结点的指针,而指向右子树的指针变为链表中指向后一个结点的指针。*/
void BiSortTree::convertBiToLink()
{if (root == NULL)return;else{convert(root);//将root指向链表的头部while (root->lchild) //root从当前位置出发,向其左孩子移动,直到左孩子为空,到达头部{root = root->lchild;}}
}
//二叉树转换成双向链表,采用中序遍历,当访问根节点的时候实现转换
void BiSortTree::convert(BiNode* bt)
{static BiNode* pre = NULL; //指向当前访问节点的前序结点if (bt == NULL){return;}else{convert(bt->lchild); //访问左子树//访问根节点if (pre == NULL) // 如果是链表的第一个节点{root = bt; // 设置链表的头部}else{pre->rchild = bt; // 将前一个节点的右指针指向当前节点bt->lchild = pre; // 将当前节点的左指针指向前一个节点}pre = bt; // 当前根节点变成前序结点convert(bt->rchild); // 访问右子树}
}
//正序输出二叉排序树链表
void BiSortTree::DisplayLink()
{BiNode* p;p = root;while (p){cout << p->data << " ";p = p->rchild;}cout << endl;
}
//逆序输出二叉排序树链表
void BiSortTree::ReverseDisplayLink()
{if (root == NULL) return; // 如果链表为空,直接返回BiNode* p = root;// 找到链表的最后一个节点while (p->rchild){p = p->rchild;}// 逆序输出while (p){cout << p->data << " ";BiNode* temp = p->lchild;delete p; // 释放节点以避免内存泄漏p = temp;}root = NULL; // 清空链表头部指针rear = NULL; // 清空链表尾部指针
}
int main()
{int n;cin >> n;int array[MAX] = { 0 };for (int i = 0; i < n; i++){cin >> array[i];}cout << "Convert binary sort tree into linked list..." << endl;BiSortTree BSTLink(array, n);BSTLink.convertBiToLink();BSTLink.DisplayLink();cout << "Reverse display link...\n";BSTLink.ReverseDisplayLink();return 0;
}