需求
请实现一个函数实现蛇形打印二叉树,即第一行从左到右的顺序打印,第二行从右到左顺序打印,第三行从左到右…….
eg:
上图二叉树打印结果为:
8
10 6
5 7 9 11
思路:
按照蛇形打印二叉树需要两个栈,在打印某一层节点时,把下一层节点存储在另一个栈中,如果打印的是奇数层,则先保存左子节点,在保存右子节点,如果是偶数层,则先保存右子节点再保存左子节点到另一个栈中。
栈的数据结构选择
因为我们要存储的节点个数未知,所以如果用数组,则会造成空间的大量浪费,所以要用链表,但是如果用单向链表时,每次出栈都要找到该出栈节点的前驱,所以会造成时间复杂度提高,为了避免这些问题,我选择了双向链表。
如图:
实现
定义栈的节点
typedef struct s{
BTNode *pb;
struct s *pa;
struct s *next;
}Stack;
入栈函数:
void pushStack(Stack **top, BTNode *pb){
//为入栈元素分配节点
Stack *s = (Stack*)malloc(sizeof(Stack));
//初始化入栈元素
s->next = NULL;
s->pa = NULL;
s->pb = pb;
if (!(*top)){
(*top) = s;
}
else{
(*top)->next = s;//新元素入栈
s->pa = (*top);//新元素的双亲指针指向双亲
(*top) = (*top)->next;//栈顶指针上移,再次指向栈顶
}
}
出栈函数:
BTNode* popStack(Stack **top){
if (!(*top)){
return NULL;//如果当前栈是空栈,
}
Stack *s = *top;//获取出栈元素
BTNode *pb = s->pb;//获取出栈元素所储存的二叉树节点地址
*top = (*top)->pa;//栈顶指针下移
if (*top){
//元素出栈后栈没有空
(*top)->next = NULL;
}
free(s);//释放出栈节点
return pb;//返回出栈元素所存储大二叉树节点地址
}
蛇形打印链表函数
void printAsSnake(BTNode *root){
int level = 0;//记录输出二叉树的层数
int thisCount = 1;//用来记录输出层剩余节点个数
int nextCount=0;//用来记录输出层下一层节点个数
Stack *stack[2] = { 0 };//将两个栈初始化为空
//先将头结点入栈
pushStack(&(stack[0]), root);
while (stack[0] || stack[1]){
//获取出栈元素
BTNode *pb = popStack(&(stack[level % 2]));
//输出出栈节点
printf("%d ",pb->data);
thisCount--;
if (level % 2){
//该层数为奇数层,叶子节点从右向左入栈
//因为改层是奇数层,所以改层的叶子节点应该入偶数栈
if (pb->right){
pushStack(&(stack[0]), pb->right);
nextCount++;
}
if (pb->left){
pushStack(&(stack[0]),pb->left);
nextCount++;
}
}
else{
//该层数为偶数层,叶子节点从左向右入栈
//因为改成是偶数层,所以改层的叶子节点应该入奇数栈
if (pb->left){
pushStack(&(stack[1]), pb->left);
nextCount++;
}
if (pb->right){
pushStack(&(stack[1]), pb->right);
nextCount++;
}
}
if (!thisCount){
//如果当前层输出完毕
printf("\n");
level++;
thisCount = nextCount;
nextCount = 0;
}
}
}
调试:
//定义二叉树的节点
typedef struct node{
int data;
struct node *left;
struct node *right;
}BTNode;
//创建二叉搜索树
BTNode* creatBinSortTree(int data[], int len){
BTNode *root = NULL, *p = NULL, *pa = NULL, *c = NULL;
for (int i = 0; i < len; i++){
//为新的节点分配单元
p = (BTNode*)malloc(sizeof(BTNode));
//初始化新节点
p->data = data[i];
p->left = p->right = NULL;
if (!root){
root = p;
}
else{
c = root;
while (c){
pa = c;
if (c->data < p->data){
c = c->right;
}
else{
c = c->left;
}
}
if (pa->data < p->data){
pa->right = p;
}
else{
pa->left = p;
}
}
}
return root;
}
int main(void){
int data[7] = { 8,10,6,5,9,7,11};
BTNode *root = creatBinSortTree(data,7);
printAsSnake(root);
system("pause");
return 0;
}
调试结果: