[英]Iterative Inorder Traversal
这是我用于迭代顺序遍历的函数。 但是当我执行它时,我遇到了分段错误。 我正在使用堆栈进行遍历。 在给定程序中,我还有一个递归函数,用于顺序遍历以检查我的create()函数是否正常工作。
我将节点推入堆栈,然后移到节点的左侧,然后从堆栈中弹出节点,然后通过root=root->rlink
将其打印并移至右侧。
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *llink;
struct node *rlink;
}Node;
typedef struct Stack
{
Node *a[10];
int top;
}stack;
void push(stack *s,Node *root)
{
if(s->top==9)
printf("FULL");
else
{
s->top++;
s->a[s->top]=root;
}
}
Node *pop(stack *s)
{
if(s->top==-1)
printf("Empty");
return s->a[s->top--];
}
void inorder(Node *root)
{
stack s;
s.top=-1;
int flag=1;
while(flag)
{
if(s.top!=9)
{
push(&s,root);
root=root->llink;
}
else{
if(s.top!=-1)
{
root=pop(&s);
printf("%d",root->data);
root=root->rlink;
}
else
flag=0;
}
}
}
void inor(Node *root)
{
if(root!=NULL)
{
inor(root->llink);
printf("%d",root->data);
inor(root->rlink);
}
}
Node *create(Node *root,int key)
{
if(root==NULL)
{
root=(Node *)malloc(sizeof(Node));
root->data=key;
root->rlink=root->llink=NULL;
}
else
{
if(key>root->data)
{
root->rlink=create(root->rlink,key);
}
else if(key<root->data)
{
root->llink=create(root->llink,key);
}
}
return root;
}
int main()
{
Node *h=NULL;
h=create(h,5);
h=create(h,1);
h=create(h,3);
h=create(h,8);
h=create(h,12);
h=create(h,51);
inorder(h);
//inor(h);
}
正如我在主要评论中所诊断的那样,问题在于当该方向上没有其他节点时,您的代码不会停止向左遍历。 解决方法很简单:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *llink;
struct node *rlink;
} Node;
typedef struct Stack
{
Node *a[10];
int top;
} stack;
static
void push(stack *s, Node *root)
{
if (s->top == 9)
printf("FULL\n");
else
{
s->top++;
s->a[s->top] = root;
}
}
static
Node *pop(stack *s)
{
if (s->top == -1)
printf("Empty\n");
return s->a[s->top--];
}
static
void inorder(Node *root)
{
stack s;
s.top = -1;
int flag = 1;
while (flag)
{
//printf("I: %p\n", (void *)root);
if (s.top != 9 && root != 0)
{
push(&s, root);
root = root->llink;
}
else
{
if (s.top != -1)
{
root = pop(&s);
printf(" %d", root->data);
root = root->rlink;
}
else
flag = 0;
}
}
}
static
void inor(Node *root)
{
if (root != NULL)
{
inor(root->llink);
printf(" %d", root->data);
inor(root->rlink);
}
}
static
Node *create(Node *root, int key)
{
if (root == NULL)
{
root = (Node *)malloc(sizeof(Node));
root->data = key;
root->rlink = root->llink = NULL;
}
else
{
if (key > root->data)
{
root->rlink = create(root->rlink, key);
}
else if (key < root->data)
{
root->llink = create(root->llink, key);
}
}
return root;
}
int main(void)
{
int nodes[] = { 37, 2, 19, 9, 7, 41 };
enum { NUM_NODES = sizeof(nodes) / sizeof(nodes[0]) };
Node *h = NULL;
h = create(h, 5);
h = create(h, 1);
h = create(h, 3);
h = create(h, 8);
h = create(h, 12);
h = create(h, 51);
printf("Recursive:\n");
inor(h);
putchar('\n');
printf("Iterative:\n");
inorder(h);
putchar('\n');
for (int i = 0; i < NUM_NODES; i++)
{
h = create(h, nodes[i]);
printf("Iterative:\n");
inorder(h);
putchar('\n');
}
}
我在函数上使用static
,因为我的默认编译器选项要求在使用前声明或定义函数,并且只能定义static
函数而无需预先声明:
gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition it37.c -o it37
您可以自行决定是否对自己很重要(但是我注意到,除了该文件之外,没有文件需要访问这些功能,因此“信息隐藏”建议这些功能应该是static
)。
样本输出:
Recursive:
1 3 5 8 12 51
Iterative:
1 3 5 8 12 51
Iterative:
1 3 5 8 12 37 51
Iterative:
1 2 3 5 8 12 37 51
Iterative:
1 2 3 5 8 12 19 37 51
Iterative:
1 2 3 5 8 9 12 19 37 51
Iterative:
1 2 3 5 7 8 9 12 19 37 51
Iterative:
1 2 3 5 7 8 9 12 19 37 41 51
如上面的注释所述,代码中的“根”总是得到左节点的分配地址,当到达叶节点时,其中具有“ NULL”值,并且您无法访问null,这就是代码失败的原因,并且会给您细分错误。
无论如何,这是我的代码来解决您的错误
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
typedef struct node
{
int data;
struct node *llink;
struct node *rlink;
}Node;
typedef struct Stack
{
Node *a[10];
int top;
}stack;
void push(stack *s,Node *root);
Node *pop(stack *s);
void inorder(Node *root);
void push(stack *s,Node *root)
{
if(s->top==9)
{
printf("FULL");
}
else
{
s->top++;
s->a[s->top]=root;
}
}
Node *pop(stack *s)
{
if(s->top==-1)
{
printf("Empty");
return NULL;
}
return s->a[s->top--];
}
void inorder(Node *root)
{
stack *s;// took it as a pointer so that i could use it easily
s=(stack *)malloc(sizeof(stack));
s->top=-1;//initialized to -1 because we increment top then insert at location indicated by top
int flag=1;
bool traverse_left=true;
while(flag)
{
if( root->llink!=NULL && traverse_left )//if left link available go left
{
push(s,root);
root=root->llink;
}
else if((root->llink==NULL&&root->rlink!=NULL)||(root->llink!=NULL && !traverse_left))
{
printf("%d ",root->data);
root=root->rlink;
traverse_left=true;
}
else if(root->llink==NULL&&root->rlink==NULL)
{
printf("%d ",root->data);
if(root->llink==NULL&&root->rlink==NULL&&s->top==-1)
{
flag=0;
}
else
{
root=pop(s);
}
traverse_left=false;
}
}
}
void inor(Node *root)
{
if(root!=NULL)
{
inor(root->llink);
printf("%d",root->data);
inor(root->rlink);
}
}
Node *create(Node *root,int key)
{
if(root==NULL)
{
root=(Node *)malloc(sizeof(Node));
root->data=key;
root->rlink=root->llink=NULL;
}
else
{
if(key>root->data)
{
root->rlink=create(root->rlink,key);
}
else if(key<root->data)
{
root->llink=create(root->llink,key);
}
}
return root;
}
int main()
{
Node *h=NULL;
h=create(h,5);
h=create(h,1);
h=create(h,3);
h=create(h,8);
h=create(h,12);
h=create(h,51);
inorder(h);
//inor(h);
}
在该程序中,每当我们向左节点移动时,我都会将该节点放在堆栈中,然后再移至左节点
当遍历堆栈是否包含左节点时,这意味着我们已经遍历了它的左树,所以我将其弹出并开始遍历它的右子树
如果节点的左右指针为空,则从堆栈中弹出该节点,然后开始遍历该节点的右子树
如果您对此答案有任何疑问,请发表评论。
顺序遍历:左,父,右
使用堆栈进行迭代遍历的关键思想是:
向左走(也推入堆栈),直到找到null
为止。
运行while循环,直到堆栈为空。 每次弹出顶部元素时,将其添加到结果列表中。 然后,如果存在正确的子代,请转到正确的子代(也推入堆栈),然后向左(也推入堆栈)直到找到null
。 因此,基本上,第1步的代码将复制到while循环内。
代码如下:
class Node {
int key;
Node left, right;
public Node() {}
public Node(int key) {
this.key = key;
}
}
public List<Integer> inOrderIterative() {
List<Integer> list = new ArrayList<>();
Stack<Node> nodeStack = new Stack<>();
Node current = root;
nodeStack.push(current);
while (null != current.left) {
current = current.left;
nodeStack.push(current);
}
while(!nodeStack.empty()) {
current = nodeStack.pop();
list.add(current.key);
if (null != current.right) {
current = current.right;
nodeStack.push(current);
while (null != current.left) {
current = current.left;
nodeStack.push(current);
}
}
}
return list;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.