<以下微软面试题全来自网络>
<以下答案与分析纯属个人观点,不足之处,还望不吝指出^_^>
题:怎样从顶部开始逐层打印二叉树结点数据?请编程。
分析:不用递归,定义两个栈(或数组),也能方便漂亮地搞定。首先栈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 =======
<今天的内容很给力,谢谢您的回顶^_^>