您的位置:首页 > 职场人生

每日微软面试题——day 3

2011-08-05 02:48 375 查看
<以下微软面试题全来自网络>

<以下答案与分析纯属个人观点,不足之处,还望不吝指出^_^>

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

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

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

/**
Author:花心龟
Blog:http://blog.csdn.net/zhanxinhang
**/
#include <stdio.h>
#include <malloc.h>

typedef struct bt_node
{
  int data;
  struct bt_node *rchild;
  struct bt_node *lchild;
}BinTree,node_t;

BinTree *myTree;

node_t* bt_new_node(int data)
{
  node_t* node = (node_t*)malloc(sizeof(node_t));
  node->rchild = NULL;
  node->lchild = NULL;
  node->data = data;

  return node;
}
void bt_create()
{
  //第一层根节点,数字11表示第一层的第一个位置,以下类似
  myTree = bt_new_node(11);

  //创建第二层节点 
  myTree->lchild = bt_new_node(21);
  myTree->rchild = bt_new_node(22); 

  //创建第三层节点
  myTree->lchild->lchild = bt_new_node(31);
  myTree->lchild->rchild = bt_new_node(32);
  myTree->rchild->lchild = bt_new_node(33);
  myTree->rchild->rchild = bt_new_node(34);

  //创建第四层节点
  myTree->rchild->rchild->rchild = bt_new_node(48);
}

void print_layer_by_layer()  //逐层打印二叉树非递归算法(主题)
{
  node_t* stack1[100]={0};//栈
  node_t* stack2[100]={0};//栈
  int T1=0,T2=0;           //栈顶下标

  stack1[T1++]=myTree;   //根节点入栈
  while(T1) //若栈为空则停止循环
    {
      while(T1)
	{
	  T1--;
	  printf("%d ",stack1[T1]->data); //打印栈顶元素
	  stack2[T2++]=stack1[T1];        //将栈元素转存到栈2中
	}
      printf("\n");

      //此时栈已存储了当前行的各元素
      //通过栈得到下一行中的节点并更新到栈中
      while(T2)  
	{
	  T2--;
	  if(stack2[T2]->rchild != NULL)
	    stack1[T1++]=stack2[T2]->rchild;

	  if(stack2[T2]->lchild != NULL)
	    stack1[T1++]=stack2[T2]->lchild;
	}
    }
}
int main()
{
  bt_create();            //创建二叉树
  print_layer_by_layer(); //逐层打印
  return 0;
}


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

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

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

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



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

/**
Author:花心龟
Blog:http://blog.csdn.net/zhanxinhang
**/
 
#include <stdio.h>
#include <malloc.h>
 
#define TEST
 
typedef struct list_node
{
  int data;
  structlist_node * next;
}list_node;
 
list_node *head; //头结点
 
void list_create()
{
  int i;
  list_node *p;
  head = (list_node*)malloc(sizeof(list_node));
  head->data=0;     //头结点数据设为
  head->next = NULL;
 
  p=head;
  for(i=1;i<6; i++) //创建5个结点
    {
      p->next = (list_node*)malloc(sizeof(list_node));
      p->next->data = i;
      p->next->next = NULL;
      p=p->next;
    }
 
#ifdef TEST
  p=head;
  while(p!=NULL)   //打印该链表
    {
      printf("%d",p->data);
      p=p->next;
    }
  printf("\n");
#endif
}
 
void list_reverse()  //使链表反序 (主题)
{
  printf("^^after reversing:\n");
  if(head == NULL || head->next==NULL) return ;//如果head为空,则返回
  list_node *p,*q;
  q=head;
  p=head->next;
 
  while(p!=NULL)
    {
    head->next=p->next; //将头指针的next指向p的下一个节点
    p->next=q;          //将p的next值反指向它的前一个节点q
    q=p;                //q移向p的位置
    p=head->next;       //p移向它的下一个位置
    }
   
    head = q;
 
#ifdef TEST
  p=head;
  while(p!=NULL)        //打印该链表
    {
      printf("%d",p->data);
      p=p->next;
    }
  printf("\n");
#endif
 
}
 
void list_destroy()  //销毁函数
{
  list_node *pmove=NULL,*pdel=NULL;
  pmove=head;
 
 while(pmove!=head)
   {
     pdel=pmove;
     free(pdel);  
     pmove=pmove->next;
   }
}
int main()
{
  list_create();   //构建单链表
  list_reverse();  //反转链表
  list_destroy();  //销毁链表
  return 0;
}


上一篇:每日微软面试题——day
2

=======
welcome to my HomePage(http://blog.csdn.net/zhanxinhang)
to have a communication =======

<今天的内容很给力,谢谢您的回顶^_^>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: