题目分析:
- 给定一个升序的单链表,将其转换为一个高度平衡的二分查找树(BST)。
解题思路:
递归实现
二叉查找树定义
二叉查找树又称有序树,是一棵空树或者具有以下性质的二叉树:
1)若任意节点的左子树不为空,则左子树上所有节点的值均小于它的根节点的值;
2)若任意节点的右子树不为空,则右子树上所有节点的值均大于它的根节点的值;
3)任意节点的左右子树也分别为二叉查找树。
方法一,借助数组实现
将有序链表存放在一个数组中,此时数组有序,然后对有序区间[left, right],取其中间mid = (left + right) / 2对应的元素作为二叉树的根节点。然后递归分别对[left, mid - 1]和[mid + 1]构造二叉搜索树即可。
方法二,不用数组实现
不使用数组,创建过程中,首先找到中间节点,然后以该点创建根节点,然后在链表的前半部分创建左子树,在链表的右半部分创建右子树即可。
实现程序
// 方法一:使用数组 struct TreeNode *createTree(vector<int> &num, int left, int right) { if (left > right) return NULL; int mid = (left + right) / 2; struct TreeNode *leftnode = createTree(num, left, mid - 1); struct TreeNode *rightnode = createTree(num, mid + 1, right); struct TreeNode *node = new TreeNode(num[mid]); node->left = leftnode; node->right = rightnode; return node; } struct TreeNode *sortedListToBST(struct ListNode *head) { if (head == NULL) return NULL; vector<int> num; // 先将数据拷贝到数组数组中,然后递归建立BST树 while (head != NULL) { num.push_back(head->val); head = head->next; } return createTree(num, 0, num.size() - 1); } // 方法二:不使用数组 struct TreeNode *createTree1(struct ListNode *start, struct ListNode *end) { if (start == end) { return NULL; } struct ListNode *p = start; struct ListNode *q = start; // 找到数组中间节点 while (q != end && q->next != end) { p = p->next; q = q->next->next; } // 创建根节点 TreeNode *root = new TreeNode(p->val); // 递归构造左子树和右子树 root->left = createTree1(start, p); root->right = createTree1(p->next, end); return root; } struct TreeNode *sortedListToBST1(ListNode *head) { return createTree1(head, NULL); }