将一个有序链表转换成一棵平衡的二叉排序树(BST),二叉排序树也称二叉搜索树。平衡指左右子树的高度差不超过1.。思路:每次查找到链表中间节点,然后一分为二。递归左右部分,继续找中间节点,一分为二。。。。。左为左子树,右边为右子树。为了加快查找中间节点的速度,可以使用快慢指针。
其代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct linknode{
int data;
struct linknode *next;
}linklist;
typedef struct treenode
{
int data;
struct treenode *left;
struct treenode *right;
}BST;
BST *sortedListtoBST(linklist *head)
{
BST *node,*mid;
linklist *slow,*fast,*preslow,*temp;
if(head==NULL)
return NULL;
if(head->next==NULL)
{
node=(BST *)malloc(sizeof(BST));
node->data=head->data;
node->left=NULL;
node->right=NULL;
return node;
}
/*用快慢指针找到中间节点*/
slow=head;
fast=head;
preslow=NULL;
while(fast->next!=NULL && fast->next->next!=NULL)
{
preslow=slow;
slow=slow->next;
fast=fast->next->next;
}
mid=(BST *)malloc(sizeof(BST));
mid->data=slow->data;
mid->left=NULL;
mid->right=NULL;
/*左右递归*/
if(preslow!=NULL)
{
preslow->next=NULL;
mid->left=sortedListtoBST(head); //左边
}
if(slow->next!=NULL)
{
mid->right=sortedListtoBST(slow->next); //右边
}
return mid;
}
void PrintBSTree(BST *BT)
{
if(BT!=NULL)
{
printf(“%d”,BT->data);
if(BT->left!=NULL || BT->right!=NULL)
{
printf(“(“);
PrintBSTree(BT->left);
if(BT->right!=NULL)
printf(“,”);
PrintBSTree(BT->right);
printf(“)”);
}
}
}
void Inorder(BST* BT)
{
if(BT!=NULL) {
Inorder(BT->left); /*中序遍历左子树*/
printf(“%d”,BT->data); /*访问根结点*/
Inorder(BT->right); /*中序遍历右子树*/
}
}
/*测试*/
void main()
{
int i;
linklist *newp,*head;
BST *root;
head=NULL;
/*生成一个有序链表*/
for(i=5;i>0;i–)
{
newp=(linklist *)malloc(sizeof(linklist));
if (newp==NULL)
{
printf(“no space!”);
exit(1);
}
newp->data=i;
newp->next=head;
head=newp;
}
root=sortedListtoBST(head);
PrintBSTree(root); //测试用
Inorder(root); //中序遍历,检查输出结果是否与有序链表一致
}