二叉排序树转双向链表(要求无任何新增节点)

题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。
  比如将二元查找树
                                         10
                                       /      \
                                    6         14
                                   /   \      /  \
                                  4    8   12    16


转换成双向链表
4=6=8=10=12=14=16。
  分析:本题是微软的面试题。很多与树相关的题目都是用递归的思路来解决,本题也不例外。

我们可以中序遍历整棵树。按照这个方式遍历树,比较小的结点先访问。如果我们每访问一个结点,假设之前访问过的结点已经调整成一个排序双向链表,我们再把调整当前结点的指针将其链接到链表的末尾。当所有结点都访问过之后,整棵树也就转换成一个排序双向链表了。


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

#define N 20

int count = 0;
typedef struct tree
{
   int num;
   struct tree* lchild;
   struct tree* rchild;
}TREE;

int add_tree(TREE** T, int num)
{
    if(*T == NULL)
     {
       *T = (TREE*)malloc(sizeof(TREE));
        (*T)->num = num;
       (*T)->lchild = NULL;
       (*T)->rchild = NULL;
     }
    else if((*T)->num < num)
      return add_tree(&((*T)->rchild),num);
    else
      return add_tree(&((*T)->lchild),num);
}

int mid_walk_tree(TREE* T)
{
    if(T!=NULL)
     {
        mid_walk_tree(T->lchild);
        count++;
        if(count%10 == 0)
         printf("%d\n",T->num);
        else
         printf("%d\t",T->num);
       
        mid_walk_tree(T->rchild);
      }
}

int convert_node(TREE* T,TREE** L)
{
   if(T == NULL)
     return 0;
     
   TREE* pCurrent = T;
  
   if(pCurrent->lchild != NULL)
     convert_node(pCurrent->lchild, L);
   
   pCurrent->lchild = *L;
   if(*L != NULL)
     (*L)->rchild = pCurrent;
    
   *L = pCurrent;
  
   
   if(pCurrent->rchild != NULL)
     convert_node(pCurrent->rchild, L);
}

TREE* tree_2_list(TREE* T)
{
   TREE* L = NULL;
   convert_node(T, &L);
  
   TREE* list_head = L;
   L->rchild = NULL;
  
   while(list_head && list_head->lchild)
     list_head = list_head->lchild;
  
   return list_head;
}

void print_list(TREE* H)
{
    count = 0;
    if(H!=NULL)
      printf("H is not null\n");
    else
      {
       printf("H is null\n");
       return;
       }
      
      
    while(H!=NULL)
     {
        count++;
        if(count%10 == 0)
          printf("%d\n",H->num);
        else
          printf("%d\t",H->num);
         
         H = H->rchild;
      }
}

int main(int argc, char *argv[])
{
   srand((unsigned)time(NULL));
   TREE* T = NULL;
   int num;
   int i = 0;
   
    for(;i<N;i++)
     {
       num = rand()%100 + 50;
       add_tree(&T, num);
     }
  
   printf("tree walk is:\n");
   mid_walk_tree(T);
  
   TREE* head = tree_2_lis t(T);
  
   printf("list walk is:\n");
   print_list(head);
  
   system("PAUSE");    
   return 0;

}
 

转载于:https://my.oschina.net/u/1167421/blog/546474

猜你喜欢

转载自blog.csdn.net/weixin_34021089/article/details/92080783