给定一个升序排列的有序单链表,将其转换为一棵平衡的二叉搜索树。
题目链接:https://oj.leetcode.com/problems/convert-sorted-list-to-binary-search-tree/
比较直观的解法是自顶向下的递归解决,先找到中间节点作为根节点,然后递归左右两部分。所有我们需要先找到中间节点,对于单链表来说,必须要遍历一边,可以使用快慢指针加快查找速度。
代码如下:
#include<iostream>
#include<queue>
using namespace std;
/* node of binary tree */
struct TreeNode
{
int data;
TreeNode* lChild;
TreeNode* rChild;
TreeNode(int _data) { data = _data; lChild = rChild = nullptr; }
};
/* node of singly-linked list */
struct ListNode
{
int data;
ListNode* next;
ListNode(int _data) { data = _data; next = nullptr; }
};
/* construct a singly-linked list */
void ConstructList(ListNode* & _head)
{
cout << "请输入一个升序的数组,以0结束: ";
int d;
ListNode* p;
cin >> d;
if (d)
{
_head = new ListNode(d);
p = _head;
while (cin >> d&&d)
{
p->next = new ListNode(d);
p = p->next;
}
}
}
/* a sorted singly-linked list to a AVL*/
TreeNode* SortedListToAVL(ListNode* & _head)
{
if (!_head) return nullptr;
if (!_head->next) return (new TreeNode(_head->data));
//用快慢指针找到中间节点
ListNode* preslow, *slow, *fast;
preslow = nullptr;
slow = fast = _head;
while (fast->next&&fast->next->next)
{
preslow = slow;
slow = slow->next;
fast = fast->next->next;
}
TreeNode* mid = new TreeNode(slow->data);
//分别递归左右两部分
if (preslow)
{
preslow->next = nullptr;
mid->lChild = SortedListToAVL(_head);
}
mid->rChild = SortedListToAVL(slow->next);
return mid;
}
/* level order of binary tree */
void LevelOrder(TreeNode* & _root)
{
cout << "二叉树的层次遍历为: ";
queue<TreeNode*> q;
q.push(_root);
while (!q.empty())
{
cout << q.front()->data << " ";
if (q.front()->lChild)
q.push(q.front()->lChild);
if (q.front()->rChild)
q.push(q.front()->rChild);
q.pop();
}
cout << endl;
}
int main()
{
ListNode* listHead;
TreeNode* TreeRoot;
ConstructList(listHead);
TreeRoot = SortedListToAVL(listHead);
LevelOrder(TreeRoot);
/*
输入:1 2 3 4 5 6 7 8 9 0
输出:5 2 7 1 3 6 8 4 9
所构造的AVL是:
5
/ \
2 7
/ \ / \
1 3 6 8
\ \
4 9
*/
return 0;
}
题目来自: http://www.acmerblog.com/convert-sorted-list-to-binary-search-tree-6124.html