morris遍历二叉树,将当前遍历到达的节点记为 cur.
cur没有左孩子:
cur 向右孩子移动.
cur有左孩子:
找到cur的左子树的最右节点记为 rightmost.
rightmost的右孩子指针指向NULL, 让其指向cur, 然后cur向左孩子移动.
rightmost的右孩子指针指向cur, 让其指向空, 然后cur向右孩子移动.
前序遍历:递归实现
void preorderRecursionTraversal( NodeBinaryTree *root ) {
if( root == NULL ) {
return;
}
printf( "%d, ", root->val );
preorderRecursionTraversal( root->left, a, aSize );
preorderRecursionTraversal( root->right, a, aSize );
}
前序遍历:迭代实现
#define NEW_STACK( s, capacity ) ({ \
*s = malloc( sizeof(**s) + sizeof((*s)->a[0]) * capacity ); \
*s->t = 0; (*s)->c = capacity; \
})
#define PUSH_STACK( s, d ) ({ s->a[s->t++] = d; })
#define POP_STACK( s, d ) ({ *d = s->a[--s->t]; })
#define EMPTY_STACK( s ) (s->t < 1)
#define FULL_STACK( s ) (s->t >= s->c)
#define DEL_STACK( s ) ({ if( s != NULL && *s != NULL ) { free( *s ); *s = NULL; } })
typedef struct Stack {
int c;
int t;
void *a[0];
} Stack;
void preorderIterativeTraversal( NodeBinaryTree *root ) {
Stack *s = NULL;
if( root != NULL ) {
NEW_STACK( &s, 10000 );
PUSH_STACK( s, root );
}
while( !EMPTY_STACK( s ) ) {
POP_STACK( s, &root );
printf( "%d, ", root->val );
if( root->right != NULL ) {
PUSH_STACK( s, root->right );
}
if( root->left != NULL ) {
PUSH_STACK( s, root->left );
}
}
DEL_STACK( &s );
}
前序遍历:morris实现
只处理第一次到达的节点.
void preorderMorrisTraversal( NodeBinaryTree *root ) {
while( root != NULL ) {
if( root->left != NULL ) {
NodeBinaryTree *rightmost = root->left;
while( rightmost->right != NULL && rightmost->right != root ) {
// cur节点的左子树的最右节点.
rightmost = rightmost->right;
}
if( rightmost->right != NULL ) {
rightmost->right = NULL;
root = root->right;
} else {
// cur节点的左子树的最右节点没有被修改过,说明是第一次到达cur节点.
printf( "%d, ", root->val );
rightmost->right = root;
root = root->left;
}
} else {
// cur节点没有子树.
printf( "%d, ", root->val );
root = root->right;
}
}
}
中序遍历:递归实现
void inorderRecursionTraversal( NodeBinaryTree *root ) {
if( root == NULL ) {
return;
}
inorderRecursionTraversal( root->left );
printf( "%d, ", root->val );
inorderRecursionTraversal( root->right );
}
中序遍历:迭代实现
#define NEW_STACK( s, capacity ) ({ \
*s = malloc( sizeof(**s) + sizeof((*s)->a[0]) * capacity ); \
*s->c = capacity; \
*s->t = 0; \
})
#define PUSH_STACK( s, d ) ({ s->a[s->t++] = d; })
#define POP_STACK( s, d ) ({ *d = s->a[--s->t]; })
#define PEEK_STACK( s, d ) ({ *d = s->a[s->t - 1]; })
#define SIZE_STACK( s ) (s->t)
#define EMPTY_STACK( s ) (s->t < 1)
#define FULL_STACK( s ) (s->t >= s->c)
#define CLEAR_STACK( s ) ({ s->t = 0; })
#define DEL_STACK( s ) ({ if( s != NULL && *s != NULL ) { free( *s ); *s = NULL; } })
typedef struct Stack {
int c;
int t;
void *a[0];
} Stack;
void inorderIterativeTraversal( NodeBinaryTree *root ) {
Stack *s = NULL;
NEW_STACK( &s, 10000 );
#if 0
while( root != NULL || !EMPTY_STACK( s ) ) {
if( root != NULL ) {
PUSH_STACK( s, root );
root = root->left;
} else {
POP_STACK( s, &root );
printf( "%d, ", root->val );
root = root->right;
}
}
#else
while( root != NULL || !EMPTY_STACK( s ) ) {
while( root != NULL ) {
PUSH_STACK( s, root );
root = root->left;
}
POP_STACK( s, &root );
printf( "%d, ", root->val );
root = root->right;
}
#endif
DEL_STACK( &s );
}
中序遍历:morris实现
只处理没有左子树的节点和第2次到达的节点.
void inorderMorrisTraversal( NodeBinaryTree *root ) {
while( root != NULL ) {
if( root->left != NULL ) {
NodeBinaryTree *rightmost = root->left;
while( rightmost->right != NULL && rightmost->right != root ) {
// cur节点的左子树的最右节点.
rightmost = rightmost->right;
}
if( rightmost->right != NULL ) {
// cur节点的左子最右节点被修改过,说明是第2次到达cur节点,
// 即cur节点的左子树已经处理完毕.
printf( "%d, ", root->val );
rightmost->right = NULL;
root = root->right;
} else {
rightmost->right = root;
root = root->left;
}
} else {
// cur节点没有左子树.
printf( "%d, ", root->val );
root = root->right;
}
}
}
后序遍历:递归实现
void postorderRecursionTraversal( NodeBinaryTree *root ) {
if( root == NULL ) {
return;
}
postorderRecursionTraversal( root->left );
postorderRecursionTraversal( root->right );
printf( "%d, ", root->val );
}
后序遍历:迭代实现
#define NEW_STACK( s, capacity ) ({ \
*s = malloc( sizeof(**s) + sizeof((*s)->a[0]) * capacity ); \
*s->c = capacity; \
*s->t = 0; \
})
#define PUSH_STACK( s, d ) ({ s->a[s->t++] = d; })
#define POP_STACK( s, d ) ({ *d = s->a[--s->t]; })
#define PEEK_STACK( s, d ) ({ *d = s->a[s->t - 1]; })
#define SIZE_STACK( s ) (s->t)
#define EMPTY_STACK( s ) (s->t < 1)
#define FULL_STACK( s ) (s->t >= s->c)
#define CLEAR_STACK( s ) ({ s->t = 0; })
#define DEL_STACK( s ) ({ if( s != NULL && *s != NULL ) { free( *s ); *s = NULL; } })
typedef struct Stack {
int c;
int t;
void *a[0];
} Stack;
// 另外一种实现:利用两个栈, 将 中左右遍历 改为 中右左遍历, 中右左过程使用栈1, 左右中过程使用栈2.
// 将 中右左过程中元素输出的地方 改为 输出元素压入栈2,
// 最后将栈2所有元素弹栈并输出, 得到左右中遍历序列, 即后序遍历.
void postorderIterativeTraversal( NodeBinaryTree *root ) {
NodeBinaryTree *lasttime = root;
Stack *s = NULL;
NEW_STACK( &s, 10000 );
if( root != NULL ) {
PUSH_STACK( s, root );
}
while( !EMPTY_STACK( s ) ) {
PEEK_STACK( s, &root );
if( root->left != NULL && root->left != lasttime && root->right != lasttime ) {
PUSH_STACK( s, root->left );
} else if( root->right != NULL && root->right != lasttime ) {
PUSH_STACK( s, root->right );
} else {
POP_STACK( s, &lasttime );
printf( "%d, ", lasttime->val );
}
}
DEL_STACK( &s );
}
后序遍历:morris实现
最先逆序处理第2次到达的节点的左子树的右边界节点,
最后逆序处理整棵树的右边界节点.
static void reverseHandleRightBoundary( NodeBinaryTree *root ) {
NodeBinaryTree *p1 = NULL, *p2 = NULL, *p3 = NULL;
for( p2 = root, p1 = NULL; p2 != NULL; p2 = p3 ) {
p3 = p2->right;
p2->right = p1;
p1 = p2;
}
for( p2 = p1, p1 = NULL; p2 != NULL; p2 = p3 ) {
printf( "%d, ", p2->val );
p3 = p2->right;
p2->right = p1;
p1 = p2;
}
}
void postorderMorrisTraversal( NodeBinaryTree *root ) {
NodeBinaryTree *cur = root;
while( cur != NULL ) {
if( cur->left != NULL ) {
NodeBinaryTree *rightmost = cur->left;
while( rightmost->right != NULL && rightmost->right != cur ) {
rightmost = rightmost->right;
}
if( rightmost->right != NULL ) {
// cur节点的左子最右节点被修改过, 说明是第二次来到cur节点.
rightmost->right = NULL;
// 逆序处理cur节点的左子树的右边界节点.
reverseHandleRightBoundary( cur->left );
cur = cur->right;
} else {
rightmost->right = cur;
cur = cur->left;
}
} else {
cur = cur->right;
}
}
// 最后逆序处理整棵树的右边界节点.
reverseHandleRightBoundary( root );
}
层次遍历:迭代实现
#define NEW_QUEUE( q, capacity ) ({ \
*q = malloc( sizeof(**q) + sizeof((*q)->a[0]) * capacity ); \
*q->c = capacity; \
*q->s = 0; \
*q->h = 0; \
})
#define ADD_QUEUE( q, d ) ({ q->a[(q->h + q->s++) % q->c] = d; })
#define POLL_QUEUE( q, d ) ({ *d = q->a[q->h]; q->h = (q->h + 1) % q->c; --q->s; })
#define PEEK_QUEUE( q, d ) ({ *d = q->a[q->h]; })
#define SIZE_QUEUE( q ) (q->s)
#define EMPTY_QUEUE( q ) (q->s < 1)
#define FULL_QUEUE( q ) (q->s >= q->c)
#define CLEAR_QUEUE( q ) ({ q->h = q->s = 0; })
#define DEL_QUEUE( q ) ({ if( q != NULL && *q != NULL ) { free( *q ); *q = NULL; } })
typedef struct Queue {
int32_t c;
int32_t s;
int32_t h;
void *a[0];
} Queue;
void levelOrderTraversal( NodeBinaryTree *root ) {
Queue *q = NULL;
NEW_QUEUE( &q, 10000 );
if( root != NULL ) {
ADD_QUEUE( q, root );
}
while( !EMPTY_QUEUE( q ) ) {
int32_t count = SIZE_QUEUE( q );
while( --count >= 0 ) {
POLL_QUEUE( q, &root );
printf( "%d, ", root->val );
if( root->left != NULL ) {
ADD_QUEUE( q, root->left );
}
if( root->right != NULL ) {
ADD_QUEUE( q, root->right );
}
}
}
DEL_QUEUE( &q );
}