微软面试题3

来源:互联网 发布:htpc安装软件 编辑:程序博客网 时间:2024/05/21 10:09

题:怎样从顶部开始逐层打印二叉树结点数据?请编程。

分析不用递归,定义两个栈(或数组),也能方便漂亮地搞定。首先栈1存储第一层中的节点也就是根节点,然后每次循环,打印栈1中的元素,再将栈1中的节点更新为下一层中的节点。总共循环logn+1次。


实现代码(以下遗漏了对二叉树的销毁操作):


view plain
  1. /** 
  2. Author:花心龟 
  3. Blog:http://blog.csdn.net/zhanxinhang 
  4. **/  
  5. #include <stdio.h>  
  6. #include <malloc.h>  
  7.   
  8. typedef struct bt_node  
  9. {  
  10.   int data;  
  11.   struct bt_node *rchild;  
  12.   struct bt_node *lchild;  
  13. }BinTree,node_t;  
  14.   
  15. BinTree *myTree;  
  16.   
  17. node_t* bt_new_node(int data)  
  18. {  
  19.   node_t* node = (node_t*)malloc(sizeof(node_t));  
  20.   node->rchild = NULL;  
  21.   node->lchild = NULL;  
  22.   node->data = data;  
  23.   
  24.   return node;  
  25. }  
  26. void bt_create()  
  27. {  
  28.   //第一层根节点,数字11表示第一层的第一个位置,以下类似  
  29.   myTree = bt_new_node(11);  
  30.   
  31.   //创建第二层节点   
  32.   myTree->lchild = bt_new_node(21);  
  33.   myTree->rchild = bt_new_node(22);   
  34.   
  35.   
  36.   //创建第三层节点  
  37.   myTree->lchild->lchild = bt_new_node(31);  
  38.   myTree->lchild->rchild = bt_new_node(32);  
  39.   myTree->rchild->lchild = bt_new_node(33);  
  40.   myTree->rchild->rchild = bt_new_node(34);  
  41.   
  42.   //创建第四层节点  
  43.   myTree->rchild->rchild->rchild = bt_new_node(48);  
  44. }  
  45.   
  46. void print_layer_by_layer()  //逐层打印二叉树非递归算法(主题)  
  47. {  
  48.   node_t* stack1[100]={0};//栈  
  49.   node_t* stack2[100]={0};//栈  
  50.   int T1=0,T2=0;           //栈顶下标  
  51.   
  52.   
  53.   stack1[T1++]=myTree;   //根节点入栈  
  54.   while(T1) //若栈为空则停止循环  
  55.     {  
  56.       while(T1)  
  57.     {  
  58.       T1--;  
  59.       printf("%d ",stack1[T1]->data); //打印栈顶元素  
  60.       stack2[T2++]=stack1[T1];        //将栈元素转存到栈2中  
  61.     }  
  62.       printf("\n");  
  63.   
  64.       //此时栈已存储了当前行的各元素  
  65.       //通过栈得到下一行中的节点并更新到栈中  
  66.       while(T2)    
  67.     {  
  68.       T2--;  
  69.       if(stack2[T2]->rchild != NULL)  
  70.         stack1[T1++]=stack2[T2]->rchild;  
  71.   
  72.       if(stack2[T2]->lchild != NULL)  
  73.         stack1[T1++]=stack2[T2]->lchild;  
  74.     }  
  75.     }  
  76. }  
  77. int main()  
  78. {  
  79.   bt_create();            //创建二叉树  
  80.   print_layer_by_layer(); //逐层打印  
  81.   return 0;  
  82. }  

另:关于此题的其它想法请看3楼我的回复,回复上的编码步骤为广度优先遍历二叉树算法,不过本人不才哈,不知题目中的意思是一层一层的打印呢,还是按照层的顺序从左到右一个一个打印呢(好像也是逐层打印),且不管它,通过对两种算法比较,上面使用栈的算法功能更强,至少打完一层可以再打一个回行。而使用队列的广度优先遍历二叉树算法有效率优势,且代码简洁易懂,就是不能打完一层后回行。^_^ 纯属个人观点,望不吝指教。


题:怎样把一个链表掉个顺序(也就是反序,注意链表的边界条件并考虑空链表)?

分析:这题比较有意思,我想了个高效的实现。首先定义两个迭代器 p 和 q,q从第一个节点开始遍历,p从第二个节点开始遍历,每次遍历将头指针的next指向p的next,然后将p的next 反指向q(此时q是p的前一个节点),也就是说将每个节点的链接方向掉过来,最后尾节点变成了头节点,头节点变成了尾节点,时间复杂度为高效的O(n)


图示:(最后一个N指空节点)


以下便是是我简洁的实现代码:

view plain
  1. /** 
  2. Author:花心龟 
  3. Blog:http://blog.csdn.net/zhanxinhang 
  4. **/  
  5.    
  6. #include <stdio.h>  
  7. #include <malloc.h>  
  8.    
  9. #define TEST  
  10.    
  11. typedef struct list_node  
  12. {  
  13.   int data;  
  14.   structlist_node * next;  
  15. }list_node;  
  16.    
  17. list_node *head; //头结点  
  18.    
  19. void list_create()  
  20. {  
  21.   int i;  
  22.   list_node *p;  
  23.   head = (list_node*)malloc(sizeof(list_node));  
  24.   head->data=0;     //头结点数据设为  
  25.   head->next = NULL;  
  26.    
  27.   p=head;  
  28.   for(i=1;i<6; i++) //创建5个结点  
  29.     {  
  30.       p->next = (list_node*)malloc(sizeof(list_node));  
  31.       p->next->data = i;  
  32.       p->next->next = NULL;  
  33.       p=p->next;  
  34.     }  
  35.    
  36. #ifdef TEST  
  37.   p=head;  
  38.   while(p!=NULL)   //打印该链表  
  39.     {  
  40.       printf("%d",p->data);  
  41.       p=p->next;  
  42.     }  
  43.   printf("\n");  
  44. #endif  
  45. }  
  46.    
  47. void list_reverse()  //使链表反序 (主题)  
  48. {  
  49.   printf("^^after reversing:\n");  
  50.   if(head == NULL) return ;//如果head为空,则返回  
  51.   list_node *p,*q;  
  52.   q=head;  
  53.   p=head->next;  
  54.    
  55.   while(p!=NULL)  
  56.     {  
  57.     head->next=p->next; //将头指针的next指向p的下一个节点  
  58.     p->next=q;          //将p的next值反指向它的前一个节点q  
  59.     q=p;                //q移向p的位置  
  60.     p=head->next;       //p移向它的下一个位置  
  61.     }  
  62.      
  63.     head = q;  
  64.    
  65. #ifdef TEST  
  66.   p=head;  
  67.   while(p!=NULL)        //打印该链表  
  68.     {  
  69.       printf("%d",p->data);  
  70.       p=p->next;  
  71.     }  
  72.   printf("\n");  
  73. #endif  
  74.    
  75. }  
  76.    
  77. void list_destroy()  //销毁函数  
  78. {  
  79.   list_node *pmove=NULL,*pdel=NULL;  
  80.   pmove=head;  
  81.    
  82.  while(pmove!=head)  
  83.    {  
  84.      pdel=pmove;  
  85.      free(pdel);    
  86.      pmove=pmove->next;  
  87.    }  
  88. }  
  89. int main()  
  90. {  
  91.   list_create();   //构建单链表  
  92.   list_reverse();  //反转链表  
  93.   list_destroy();  //销毁链表  
  94.   return 0;  


原创粉丝点击