c - 为什么我的 C 结构必须添加一个奇怪的 int 并且它会影响指针?
问题描述
这是一个二叉树队列问题
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define NUM 10
typedef struct _node
{
int value;
struct _node *left;
struct _node *right;
}TNode,*Tree;
在 q_node 中添加 *next 是我的目的,否则,我们需要在 Tree 节点结构中添加所以,为了不修改树的结构,我设计了一个 q_node 结构来包含它,我们可以使用定义命令来制作它作为一个模板。
typedef struct _q_node
{
TNode *t_node;
int length;
struct _q_node *next;
}QNode;
typedef struct _Queue
{
QNode *head;
QNode *tail;
}Queue;
Queue* init_queue()
{
Queue *queue=(Queue*)malloc(sizeof(Queue));
queue->head = queue->tail = NULL;
return queue;
}
int enQueue(Queue *pQueue,TNode *pTNode)
{
QNode *pQNode = (QNode *)malloc(sizeof(QNode));
pQNode->t_node = pTNode;
if(pQueue->head == NULL)
{//when it's empty
pQueue->head = pQNode;
pQueue->tail = pQNode;
}
else
{
pQueue->tail->next = pQNode;
pQueue->tail = pQNode;
}
}
QNode* deQueue(Queue *pQueue)
{
if(pQueue->head == NULL)
{
return NULL;
}
QNode *deNode= pQueue->head;
pQueue->head = pQueue->head->next;
return deNode;
}
TNode* init_TNode(int value)
{
TNode *new_node = (TNode*)malloc(sizeof(TNode));
new_node->value=value;
new_node->left = new_node->right = NULL;
return new_node;
}
//0:empty
int ifEmpty(Queue *pQueue)
{
if(pQueue->head == NULL)
{
//printf("empty tree\n");
return 0;
}
//printf("queue is not empty\n");
return 1;
}
int insert_tree(Tree pTree,int pValue)
{
//found NULL sub tree, then add to his father->left
if(!pTree)
{
return 0;
}
TNode *tNode = init_TNode(pValue);
if(tNode==NULL)
{
printf("create TNode error!\n");
return 0;
}
if(pValue < pTree->value)
if(insert_tree(pTree->left,pValue)==0)
{
//no left child any more,set a new left child to pTree
pTree->left = tNode;
printf("insert :%d\n",pValue);
}
if(pValue > pTree->value)
if(insert_tree(pTree->right,pValue)==0)
{
pTree->right = tNode;
printf("insert :%d\n",pValue);
}
}
Tree creatTree()
{
srand(time(NULL));
Tree root = init_TNode(rand()%100);
printf("root is %d\n",root->value);
int i ;
for(i=1;i<NUM;i++)
{
insert_tree(root,rand()%100);
}
printf("creat tree succuess!Tree heigh is:%d\n",get_tree_height(root));
return root ;
}
int get_tree_height(Tree pRoot)
{
if(!pRoot)
{
return 0;
}
int lh=0,rh=0;
lh = get_tree_height(pRoot->left);
rh = get_tree_height(pRoot->right);
return (lh<rh)?(rh+1):(lh+1);
}
int breath_travel(Tree pRoot,Queue *pQueue)
{
if(!pRoot)
{
return 0;
}
enQueue(pQueue,pRoot);
printf("_______________________\n");
printf("breath begin,enter root:\n");
while(ifEmpty(pQueue)!=0)
{
QNode *qNode = deQueue(pQueue);
//make suer every enQueue Node is not NULL
if(qNode->t_node->left!=NULL)
{enQueue(pQueue,qNode->t_node->left);}
if(qNode->t_node->right!=NULL)
{
enQueue(pQueue,qNode->t_node->right);
}
//print the tree node value
printf("%d ",qNode->t_node->value);
}
printf("\n-----------\nbreath end!\n-----------\n");
return 1;
}
int main()
{
Queue *queue=init_queue();
int i;
ifEmpty(queue);
printf("insert node to queue\n");
Tree root = creatTree();
if(!root)
{
printf("create Tree failed!\n");
return 0;
}
breath_travel(root,queue);
// free(queue);
return 0;
}
如果此版本可以在我的计算机上正常运行,我必须在开头的“_q_node”结构中添加一个未使用的 int “int length”,如果我不添加它,ifEmpty 函数无法找到正确的位置,如“pQueue->head = = 空"
为什么会这样?
解决方案
您的程序在insert_tree
函数中存在错误。我在您的代码中添加了一些注释:
int insert_tree(Tree pTree,int pValue)
{
//found NULL sub tree, then add to his father->left
if(!pTree)
{
return 0;
}
TNode *tNode = init_TNode(pValue);
if(tNode==NULL)
{
printf("create TNode error!\n");
return 0;
}
if(pValue < pTree->value)
if(insert_tree(pTree->left,pValue)==0) // Here the return value is used
{
//no left child any more,set a new left child to pTree
pTree->left = tNode;
printf("insert :%d\n",pValue);
}
if(pValue > pTree->value)
if(insert_tree(pTree->right,pValue)==0) // Here the return value is used
{
pTree->right = tNode;
printf("insert :%d\n",pValue);
}
// No return value here !!
}
正如您从我的评论中看到的那样,您错过了函数末尾的返回值。由于您在其他地方使用该返回值,因此您的程序使用了一些未初始化的返回值。这会使你的程序失败。
顺便说一句:enQueue
也错过了返回值。
建议:始终以高警告级别编译代码,并将所有警告视为错误。换句话说 - 如果有警告,则应在运行代码之前对其进行修复。
如果您使用gcc
use进行编译-Wall
以获取所有警告
除此之外,我认为这个函数的逻辑有问题。它使用递归来查找插入新值的位置。在每个递归调用中,您使用创建一个新节点,TNode *tNode = init_TNode(pValue);
但您仅在递归结束时使用它。换句话说,您似乎有内存泄漏。
此外,尚不清楚您如何/在何处处理pValue
等于的情况pTree->value
顺便说一句:pValue
对于整数来说是一个真正的坏名字,因为它p
会让你认为它是一个指针。
推荐阅读
- ios - 为什么我无法快速看到响应值?
- wordpress - 我在 head 结尾之前添加的 Wordpress CSS 不会覆盖来自链接样式表的 CSS
- python - 无法访问声明的全局变量
- java - 无法在 VSCode 中运行 JUnit。AssertEquals 符号无法识别
- php - PHP-FPM 禁止所有连接
- python-sphinx - 使用 sphinx-bootstrap-theme 为 globaltoc 声明最大深度的正确方法是什么?
- spring - 如何使用 Spring Boot 在 API 删除方法中传递多个 id
- actframework - 格式无效的 JWT
- python - 如何以更快的方式计算小计?
- c# - 如何使用已经过身份验证的访问令牌来启动 SheetService,这样我就不必启动新的身份验证