代码能运行,但是最后崩溃了,挂掉了。
问题背景是我想创建一个二叉树并前序中序递归遍历打印并最后释放所有空间。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef struct Node
{
char data;
struct Node *lchild;
struct Node *rchild;
}bitnode;
void createtree(bitnode **T)
{
assert(*T);
char ch;
scanf("%c", &ch);
while (getchar() != '\n');
if (ch == '#')
*T = NULL;
else
{
*T = (bitnode*)malloc(sizeof(bitnode));
(*T)->data = ch;
createtree(&((*T)->lchild));
createtree(&((*T)->rchild));
}
}
void 前序遍历(bitnode **T)
{
if (*T == NULL)
{
return;
}
printf("%d ", (*T)->data);
前序遍历(&((*T)->lchild));
前序遍历(&((*T)->rchild));
}
void 中序遍历(bitnode **T)
{
if (*T == NULL)
{
return;
}
中序遍历(&((*T)->lchild));
printf("%d ", (*T)->data);
中序遍历(&((*T)->rchild));
}
void 释放内存空间(bitnode** T)
{
if (*T == NULL)
{
return;
}
/bitnode cur = T;/
while (T != NULL)
{
释放内存空间(&((*T)->lchild));
释放内存空间(&((*T)->rchild));
free(T);
}
}
int main()
{
bitnode * T;
/T->lchild = NULL;
T->rchild = NULL;/
/bitnode * p = T;/
printf("先序递归创建\n");
createtree(&T); //这里传入指针的地址
前序遍历(&T);
中序遍历(&T);
释放内存空间(&T);
return 0;
}
最后出来一个框
怎么着都不行了
不想程序崩溃。正确运行应该怎样改代码?
我编辑的时候看着好好的,一发出来全都挤在一块我也不知道该怎么办了,劳烦大家废废眼睛了,谢谢大家。
释放的循环也应该针对*T,而不是T
释放内存处有误,在释放左右子节点之后,释放T,此时T这个变量已经没有了,但是while循环依旧在使用T。因为有递归释放,所以不需要while循环,将其修改为
void freeMemory(bitnode *T) {
if (T == NULL) {
return;
}
freeMemory(T->lchild);
freeMemory(T->rchild);
free(T);
}
回答不易,解决问题了请给一个采纳,谢谢!!
另外还有一些无关紧要的小细节,完整的代码参考如下
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
char data;
struct Node *lchild;
struct Node *rchild;
} bitnode;
bitnode *createtree() {
char ch;
scanf("%c", &ch);
while (getchar() != '\n')
;
if (ch == '#')
return NULL;
bitnode *T = (bitnode *)malloc(sizeof(bitnode));
T->data = ch;
T->lchild = createtree();
T->rchild = createtree();
return T;
}
void preorder(bitnode *T) {
if (T == NULL) {
return;
}
printf("%d ", T->data);
preorder(T->lchild);
preorder(T->rchild);
}
void inorder(bitnode *T) {
if (T == NULL) {
return;
}
inorder(T->lchild);
printf("%d ", T->data);
inorder(T->rchild);
}
void freeMemory(bitnode *T) {
if (T == NULL) {
return;
}
freeMemory(T->lchild);
freeMemory(T->rchild);
free(T);
}
int main() {
bitnode *T;
printf("先序递归创建\n");
T = createtree(T); //这里传入指针的地址
printf("先序遍历的结果:");
preorder(T);
printf("\n中序遍历的结果:");
inorder(T);
freeMemory(T);
printf("\n释放内存完毕!");
return 0;
}
修改如下供参考,修改处见注释:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef struct Node
{
char data;
struct Node* lchild;
struct Node* rchild;
}bitnode;
void createtree(bitnode** T)
{
assert(*T);
char ch;
scanf(" %c", &ch);
//while ((getchar()) != '\n'); 修改
if (ch == '#')
(*T) = NULL;
else
{
(*T) = (bitnode*)malloc(sizeof(bitnode));
(*T)->data = ch;
createtree(&((*T)->lchild));
createtree(&((*T)->rchild));
}
}
void Preordertraversal(bitnode* T) //void 前序遍历(bitnode** T)修改
{
if (T == NULL) //修改
return;
printf("%d ", T->data); //修改
Preordertraversal(T->lchild); //前序遍历(T->lchild);修改
Preordertraversal(T->rchild); //前序遍历(T->rchild);修改
}
void inordertraversal(bitnode* T) //void 中序遍历(bitnode** T)修改
{
if (T == NULL) //(*T == NULL)修改
return;
inordertraversal(T->lchild); //中序遍历(&((*T)->lchild));修改
printf("%d ", T->data); // (*T)->data 修改
inordertraversal(T->rchild); //中序遍历(&((*T)->rchild));修改
}
void release(bitnode* T)//void 释放内存空间(bitnode** T)修改
{
if (T == NULL)//(*T == NULL) 修改
return;
// bitnode cur = T; 修改
//while (T != NULL) 修改
//{
release(T->lchild); //释放内存空间(&((*T)->lchild));修改
release(T->rchild); //释放内存空间(&((*T)->rchild));修改
printf("\n"); //修改
printf("%c 被释放了", T->data);//修改
free(T);
//}
}
int main()
{
bitnode* T;
// T->lchild = NULL;
//T->rchild = NULL; /
//bitnode * p = T; /
printf("先序递归创建\n");
createtree(&T); //这里传入指针的地址
Preordertraversal(T); //前序遍历(&T);修改
printf("\n");
inordertraversal(T); //中序遍历(&T);修改
release(T); //释放内存空间(&T);修改
return 0;
}
可以参考一下
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int Count = 0; /*统计二叉树节点*/
int Depth = 0; /*二叉树的深度*/
/*二叉树结构*/
typedef struct BNode
{
char data; /*字符*/
int weight; /*出现次数,即权重*/
struct BNode *left,*right; /*左子女,右子女*/
}BTNode,*BTree;
/*字符和出现频率的映射表*/
typedef struct
{
char data; /*字符*/
int weight; /*出现次数,即权重*/
int level; /*该字符所在二叉树层次*/
}chart;
/*创建字符和频率映射表*/
chart * CreateChart()
{
int i;
chart *List = (chart *)malloc(sizeof(chart) * Count); /*动态分配有NUM个chart*类型单元的数组*/
/*循环方式建立List表*/
for (i = 0 ; i < Count ; i++)
{
printf("Please enter the character of NO%d.:\n",i+1); /*输入字符*/
fflush(stdin);
scanf("%c",&List[i].data);
fflush(stdin);
printf("Please enter the weight of NO%d.:\n",i+1); /*输入权重*/
scanf("%d",&List[i].weight);
List[i].level = 0;
}
return List;
}
/*插入一个数据,数据左小右大*/
int Insert(BTree root,char Data,int weight)
{
int level = 1; /*level代表该节点插入的层次*/
BTree temp,father,child; /*temp是临时结点,father是对比结点的父结点,child是当前对比结点。*/
/*创建临时结点*/
temp = (BTree)malloc(sizeof(BTNode));
temp->data = Data;
temp->weight = weight;
temp->left = NULL;
temp->right = NULL;
child = root;
/*该临时结点的挂链*/
while (child)
{
father = child;
if (child->weight > temp->weight) /*权重小的放在左边*/
child = child->left;
else /*权重大的放在右边*/
child = child->right;
level++;
}
if (father->weight > temp->weight)
father->left = temp;
else
father->right = temp;
return level;
}
/*创建二叉树*/
BTree CreateBTree(chart *List)
{
int i;
BTree root;
/*创建根节点*/
root = (BTree)malloc(sizeof(BTNode));
root->data = List[0].data;
root->weight = List[0].weight;
root->left = NULL;
root->right = NULL;
List[0].level=1;
Depth = 1;
/*创建其余节点*/
for (i=1;i<Count;i++)
{
List[i].level = Insert(root,List[i].data,List[i].weight);
if (Depth < List[i].level)
Depth = List[i].level;
}
return root;
}
/*先序遍历*/
void PreOrderTraverse(BTree root)
{
if (root)
{
printf("\t%c",root->data);
PreOrderTraverse(root->left);
PreOrderTraverse(root->right);
}
}
/*中序遍历*/
void InOrderTraverse(BTree root)
{
if(root)
{
InOrderTraverse(root->left);
printf("\t%c",root->data);
InOrderTraverse(root->right);
}
}
/*后序遍历*/
void PostOrderTraverse(BTree root)
{
if(root)
{
PostOrderTraverse(root->left);
PostOrderTraverse(root->right);
printf("\t%c",root->data);
}
}
/*统计输出二叉树每层节点数*/
void NodeNum(chart *List)
{
int i,L; /*L是每个字符所在二叉树的层数*/
int *llevel; /*llevel指向存储每层结点的数组*/
llevel= (int *)malloc(sizeof(int) * (Depth+1) ) ; /*建立一个拥有Depth+1个单元的数组,用来存储每层节点数。*/
memset(llevel, 0, sizeof(int) * (Depth+1));
/*统计每层节点数*/
for (i = 0; i < Count; i++)
{
L=List[i].level;
llevel[L]++;
}
/*输出每层节点数*/
for(i = 1; i < Depth+1; i++)
{
printf("Level %d has %d nodes.\n", i, llevel[i] );
}
}
/*主程序*/
int main(void)
{
chart *List; /*List是字符和频率的映射表*/
BTree root; /*root是二叉树的根节点*/
printf("Please enter the number of characters:\n");/*设置字符总数*/
scanf("%d",&Count);
List = CreateChart();
root = CreateBTree(List);/*创建二叉树*/
system("cls");
/*先序输出*/
printf("\n先序输出\n");
PreOrderTraverse(root);
/*中序输出*/
printf("\n中序输出\n");
InOrderTraverse(root);
/*后序输出*/
printf("\n后序输出\n");
PostOrderTraverse(root);
/*输出二叉树节点总数*/
printf("\nThe number of nodes of binary tree is: %d.\n",Count);
/*统计并输出该二叉树的深度*/
printf("\nThe number of level of binary tree is: %d\n",Depth);
/*输出每层有几个节点*/
NodeNum(List);
return 0;
}
https://blog.csdn.net/weixin_42245157/article/details/80457578