C语言:二元查找树转变成排序的双向链表

题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。

要求不能创建任何新的结点,只调整指针的指向。

本题目是微软的算法题,正好之前做过二叉树的遍历算法。就在之前的基础上面研究,发现之前的题目上用的是二元查找树。遍历方法正好是顺序遍历。就在此基础上做了修改,实现算法。方法就是递归。然后,就是记录之前的节点,和当前节点左右指针做转换。因为当前节点,正好是比前一个节点第二大的数据。 

#include <stdio.h>
#include <stdlib.h>

typedef    int DataType;

typedef struct tree  
{  
    DataType data;  
    struct tree *left;  
    struct tree *right;  
}node,*pnode;  
  
pnode createTreeNode(DataType data)  
{  
    pnode n=(pnode)malloc(sizeof(node));  
    n->data = data;  
    n->left = NULL;  
    n->right = NULL;  
    return n;  
  
}

void treeTravel(pnode p)  
{  
    if (NULL == p)  
    {  
        return;  
    }  
    treeTravel(p->left);  
    printf("%d  ", p->data);  
    treeTravel(p->right);  
  
}

pnode ConvertNode(pnode p)  
{  
	static pnode left_node = NULL;
	static pnode right_node = NULL;
	static pnode head_node = NULL;

    if (NULL == p)  
    {  
        return head_node;  
    }

    ConvertNode(p->left);

	if(left_node == NULL)
	{
		left_node = p;
		left_node->left = NULL;
		head_node = left_node;
	}
	else
	{
		right_node = p;
		left_node->right = right_node;
		right_node->left = left_node;
		left_node = right_node;
	}

    ConvertNode(p->right);

	return head_node;
}

int countNode(pnode p)
{
	if(p){	
		return(countNode(p->left) +  countNode(p->right) + 1);
	}
	
	return 0;
}

int countLeafNode(pnode p)
{
	if(p){
		if((p->left == NULL) && (p->right == NULL))return 1;
	
		return(countLeafNode(p->left) +  countLeafNode(p->right));
	}
	
	return 0;
}

/* 
              7 1 5 6 2 9 4 8 6 
 
              7 
	
         1         9 
             5   8 
          3   6   
        2   4 

*/  
void main()  
{  
    pnode root=NULL;
	int NodeNumber = 0;
	int leafNodeNumber = 0;
  
    pnode p1=NULL, p2=NULL, p3=NULL, p4=NULL, p5=NULL, p6=NULL, p7=NULL,p8=NULL,p9=NULL;  
  
    p1 = createTreeNode(7);  
    p2 = createTreeNode(1);  
    p3 = createTreeNode(9);  
    p4 = createTreeNode(5);  
    p5 = createTreeNode(8);  
    p6 = createTreeNode(3);  
    p7 = createTreeNode(6);  
    p8 = createTreeNode(2);  
    p9 = createTreeNode(4);  
  
    p1->left = p2;  
    p1->right = p3;  
  
    p2->right = p4;  
  
    p3->left = p5;  
  
    p4->left = p6;  
    p4->right = p7;  
  
    p6->left = p8;  
    p6->right = p9;  
      
    root = p1;  
    treeTravel(root);  

	NodeNumber = countNode(root);
	leafNodeNumber = countLeafNode(root);

	printf("\n");
	printf("node number = %d\n", NodeNumber);
	printf("leaf node number = %d\n", leafNodeNumber);

	pnode travel_node;
	travel_node = ConvertNode(root);
	while(travel_node)
	{
		printf("%d  ", travel_node->data);
		travel_node = travel_node->right;

	}

	printf("\n");

	getchar();  
}  

kent@ubuntu:~/source/Microsoft$ ./a.out
1  2  3  4  5  6  7  8  9  
node number = 9
leaf node number = 4
1  2  3  4  5  6  7  8  9 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AllenSun-1990

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值