// rogram received signal SIGABRT, Aborted.
// __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49
// 49 ../sysdeps/unix/sysv/linux/raise.c: 没有那个文件或目录.
这是为啥
当在主函数中出现两个层序遍历时就出现问题
但是当把int pop(Queue *pqueue)中的free()函数注释掉就可以。
代码:
主函数:
#include <stdio.h>
#include <stdlib.h>
#include "tree.h"
int main (void)
{
Tree_Node *root=(Tree_Node *)malloc(sizeof(Tree_Node));
init(root,23);
insert(root,15);
insert(root,25);
insert(root,24);
insert(root,27);
insert(root,7);
insert(root,16);
insert(root,3);
insert(root,9);
insert(root,8);
printf("中序遍历:\n");
inorder(root);
// 层序遍历
putchar('\n');
level_order(root);
// level_order(root);
// putchar('\n');
// level_order(root);
// reverse(root);
// printf("翻转后的中序遍历:\n");
// inorder(root);
// putchar('\n');
// putchar('\n');
putchar('\n');
printf("该树的深度为:%d\n",treedepth(root));
printf("该树中的最小值为:\n");
dispaly(findmin(root));
putchar('\n');
printf("该树中的最大值为:\n");
dispaly(findmax(root));
putchar('\n');
dispaly(find(root,23));
putchar('\n');
root=Delete(root,23);
printf("中序遍历:\n");
inorder(root);
putchar('\n');
level_order(root);
putchar('\n');
root=Delete(root,9);
printf("中序遍历:\n");
inorder(root);
putchar('\n');
root=Delete(root,3);
printf("中序遍历:\n");
inorder(root);
putchar('\n');
// level_order(root);
return 0;
}
tree.h:
/*
树的实现
*/
#ifndef _TREE_H
#include <stdbool.h>
typedef int ElementType;
// // 树的定义
// typedef struct tree_node{
// ElementType data;
// struct tree_node *firstchild; // 第一个儿子
// struct tree_node *nextsibling; // 下一个(第一个)兄弟
// }Tree_NOde;
// 二叉树的定义
typedef struct tree_node{
ElementType data;
struct tree_node *leftchild;
struct tree_node *rightchild;
// struct tree_node *parent; // 双亲结点
}Tree_Node;
// 层序遍历所使用的队列
typedef struct queue{
struct queue *prev;
struct queue *next;
int data;
// int size;
}Node;
typedef struct sq{
Node *head;
int size;
}Queue;
// 初始化队列
void init_queue(Queue *pqueue);
// 向队列中插入一个元素
void push(Queue *pqueue, int value);
// 从队列中取出一个数据
int pop(Queue *pqueue);
// 清空队列
void mkempty_queue(Queue *pqueue);
// 初始化树
void init(Tree_Node *root, ElementType e);
// 判断该节点是否是树叶
bool is_leaf(Tree_Node *pnode);
// 清空树
void mkempty(Tree_Node *root);
// 查找一个特定元素所在的节点
Tree_Node *find(Tree_Node *root, ElementType e);
// 查找二叉树中的最小值
Tree_Node *findmin(Tree_Node *root);
// 查找二叉树中的最大值
Tree_Node *findmax(Tree_Node *root);
// 插入一个元素,并返回二叉树的根节点
Tree_Node *insert(Tree_Node *root, ElementType e);
// 删除一个元素所在的节点,并返回根节点
Tree_Node *Delete(Tree_Node *root, ElementType e);
// 二叉树的翻转
Tree_Node *reverse(Tree_Node *root);
// 中序遍历二叉树
void inorder(Tree_Node *root);
// 读取该节点的信息
void dispaly(Tree_Node *pnode);
// 先序遍历
void preorder(Tree_Node *root);
// 后续遍历
void postorder(Tree_Node *root);
// 求二叉树的高度
int treedepth(Tree_Node *root);
// 层序遍历
void level_order(Tree_Node *root);
// 得到某个节点的信息
int get_data(Tree_Node *pnode);
// 交换两个节点
void exchange(Tree_Node *p);
#endif
tree.c:
/*
tree.h中的函数实现
*/
#include "tree.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void init(Tree_Node *root, ElementType e)
{
memcpy(&root->data,&e,sizeof(ElementType));
root->leftchild=NULL;
root->rightchild=NULL;
}
bool is_leaf(Tree_Node *pnode)
{
if(pnode->rightchild==NULL && pnode->leftchild==NULL)
return true;
else
return false;
}
void mkempty(Tree_Node *root)
{
if(root==NULL)
return;
mkempty(root->leftchild);
mkempty(root->rightchild);
free(root);
}
Tree_Node *find(Tree_Node *root, ElementType e)
{
if(root==NULL)
return NULL;
if(e>root->data)
return find(root->rightchild,e);
else if(e<root->data)
return find(root->leftchild,e);
else
return root;
}
Tree_Node *findmin(Tree_Node *root)
{
if(root==NULL)
return NULL;
if(root->leftchild==NULL)
return root;
else
return findmin(root->leftchild);
// return root;
}
Tree_Node *findmax(Tree_Node *root)
{
if(root==NULL)
return NULL;
if(root->rightchild==NULL)
return root;
else
return findmax(root->rightchild);
}
Tree_Node *insert(Tree_Node *root, ElementType e)
{
if(root==NULL) // 找到位置,进行插入
{
root=(Tree_Node *)malloc(sizeof(Tree_Node));
if(root==NULL)
{
printf("内存分配失败\n");
return NULL;
}
memcpy(&root->data,&e,sizeof(ElementType));
// printf("插入:%d\t",root->data);
root->leftchild=NULL;
root->rightchild=NULL;
}
else if(e>root->data)
root->rightchild=insert(root->rightchild,e);
else if(e<root->data)
root->leftchild=insert(root->leftchild,e);
// printf("aaa\n") ;
// inorder(root);
// printf("\n");
return root;
}
Tree_Node *Delete(Tree_Node *root, ElementType e)
{
if(root==NULL)
return NULL;
else
{
if(e>root->data)
root->rightchild=Delete(root->rightchild,e);
else if(e<root->data)
root->leftchild=Delete(root->leftchild,e);
else
{
if(root->leftchild!=NULL && root->rightchild!=NULL) // 有两棵子树
{
Tree_Node *temp=findmin(root->rightchild);
memcpy(&root->data,&temp->data,sizeof(ElementType));
root->rightchild=Delete(root->rightchild,root->data); // 删除代替的那个节点
}
else // 只有一棵子树或者没有子树
{
Tree_Node *t=root;
if(t->rightchild==NULL)
root=root->leftchild; // 当t为叶子节点时,确保它的父节点指向该节点的那个指针为NULL,
else if(t->leftchild==NULL)
root=root->rightchild;
free(t);
}
}
}
return root;
}
void dispaly(Tree_Node *pnode)
{
if(pnode==NULL)
return ;
else
printf("%d,",pnode->data);
}
void inorder(Tree_Node *root)
{
if(root==NULL)
return ;
inorder(root->leftchild);
dispaly(root);
inorder(root->rightchild);
}
void preorder(Tree_Node *root)
{
if(root==NULL)
return ;
dispaly(root);
preorder(root->leftchild);
preorder(root->rightchild);
}
void postorder(Tree_Node *root)
{
if(root==NULL) return ;
postorder(root->leftchild);
postorder(root->rightchild);
dispaly(root);
}
int treedepth(Tree_Node *root)
{
if(root==NULL)
return -1;
int llenth=treedepth(root->leftchild);
int rlenth=treedepth(root->rightchild);
return llenth>rlenth?llenth+1:rlenth+1;
}
void init_queue(Queue *pqueue)
{
pqueue->head=(Node *)malloc(sizeof(Node));
pqueue->head->next=pqueue->head->prev=NULL;
pqueue->size=0;
}
void push(Queue *pqueue, int value)
{
Node *head=pqueue->head;
while(head->next!=NULL)
head=head->next;
Node *n=(Node *)malloc(sizeof(Node));
n->prev=head;
head->next=n;
n->next=NULL;
n->data=value;
pqueue->size++;
}
int pop(Queue *pqueue)
{
Node *n=pqueue->head->next; // 第一个数据节点
if(n!=NULL)
{
pqueue->size--;
int result=n->data;
pqueue->head->next=n->next;
if(n->next!=NULL)
{
n->next->prev=pqueue->head;
}
free(n); // 这里存在问题,将这里注释后就能正常运行多次层序遍历
n->next=NULL;
n->prev=NULL;
return result;
}
else
{
printf("队列为空\n");
exit(1);
}
}
void mkempty_queue(Queue *pqueue)
{
Node *first=pqueue->head->next;
while(first!=NULL)
{
pqueue->size--;
Node *n=first->next;
free(first);
first->next=first->prev=NULL;
}
}
void level_order(Tree_Node *root)
{
printf("层序遍历:\n");
Queue *pq=(Queue *)calloc(1,sizeof(Queue));
init_queue(pq);
int a=get_data(root);
push(pq,a);
while(pq->size!=0)
{
int t=pop(pq);
printf("%d ",t);
Tree_Node *temp=find(root,t);
Tree_Node *l_child=temp->leftchild;
Tree_Node *r_child=temp->rightchild;
if(l_child!=NULL)
{
int l=get_data(l_child);
push(pq,l);
}
if(r_child!=NULL)
{
int r=get_data(r_child);
push(pq,r);
}
// int r
}
mkempty_queue(pq);
free(pq);
putchar('\n');
}
// int get_size(Tree_Node *root)
// {
// if(root==NULL)
// return 0;
// }
int get_data(Tree_Node *pnode)
{
if(pnode!=NULL)
return pnode->data;
else
{
printf("该节点空\n");
exit(1);
}
}
Tree_Node *reverse(Tree_Node *root)
{
if(root==NULL)
return NULL;
Tree_Node *temp=root->leftchild;
root->leftchild=reverse(root->rightchild); // 翻转左子树
root->rightchild=reverse(temp); // 翻转右子树
// exchange(root); // 交换root的左右子节点
return root; // 返回root;
}
void exchange(Tree_Node *p)
{
if(p==NULL)
return ;
Tree_Node *temp=p->leftchild;
p->leftchild=p->rightchild;
p->rightchild=temp;
}