【发布时间】:2018-03-23 03:18:48
【问题描述】:
我正在尝试打印链接列表的所有成员。我正在遍历列表并计算列表中整数的重复副本(如果有)。但是当我再次遍历列表以检查重复副本时,我的 ipNext 指向 null 终止我之前的遍历循环。
插入数据函数:
void insertIP(bstNode *head, char user[], int ip){
if(head != NULL){
bstNode* startList = head;
while ((startList) && (strcmp(startList->data, user) != 0) ){
if(strcmp(user, startList->data)<0)
{
startList=startList->left;
}
else if(strcmp(user, startList->data)>0)
{
startList=startList->left;
}
}
if (startList != NULL){
IP* new = (IP*)malloc(sizeof(IP));
new->ip = ip;
//new->count = (new->count + 1);
new->ipNext=NULL;
IP* temp = startList->ipHead;
startList->ipHead = new;
new->ipNext = temp;
}
}
}
迭代函数,它查找特定数据条目并计算它在链表中出现的次数(如果有)。
bstNode* search(char* key, bstNode* root)
{
int res;
bstNode *leaf = root;
if( leaf != NULL ) {
res = strcmp(key, leaf->data);
if( res < 0)
search( key, leaf->left);
else if( res > 0)
search( key, leaf->right);
else
{
printf("\n'%s' found!\n", key);
//int count = 0;
bstNode *temp = leaf;
while (temp->ipHead != NULL) {
int tempip = temp->ipHead->ip;
int ipcount = 0;
uint32_t ip = tempip;
struct in_addr ip_addr;
ip_addr.s_addr = ip;
bstNode *cpy = leaf;
ipcount = count(&cpy, tempip);
//temp = leaf;
printf("The IP address is %s\n C:%d\n", inet_ntoa(ip_addr), ipcount);
temp->ipHead = temp->ipHead->ipNext;
}
}
}
else printf("\nNot in tree\n");
return leaf;
}
支持函数(这会将 ipNext 值设置为 null,从而终止搜索循环。即使我传递了指针的副本,我认为这是我的问题)。
int count(bstNode** start, int item)
{
bstNode* current = *start;
int count = 0;
while (current->ipHead->ipNext != NULL)
{
if (current->ipHead->ip == item)
{
count++;
}
current->ipHead = current->ipHead->ipNext;
}
return count;
}
数据结构声明:
typedef struct ip{
int ip;
struct ip *ipNext;
}IP;
typedef struct bstNode
{
char data[32];
struct bstNode* left;
struct bstNode* right;
IP *ipHead;
}bstNode;
BST 插入函数:
bstNode *insert(bstNode *root, char *word, int ip)
{
bstNode *node = root;
if(node==NULL){
node= malloc(sizeof(bstNode));
//IP* ipNode=malloc(sizeof(IP));
strcpy(node->data, word);
node->left=NULL;
node->right=NULL;
insertIP(node, word, ip);
}
else{
if(strcmp(word, node->data)<0)
node->left=insert(node->left, word, ip);
else if(strcmp(word, node->data)>0)
node->right=insert(node->right, word,ip);
else if(strcmp(word, node->data) == 0) {
insertIP(node, word, ip);
}
}
return node;
}
感谢大家的帮助!
【问题讨论】:
-
current->ipHead = current->ipHead->ipNext- 对于应该只读遍历链表和计数节点的函数来说,这是一个真的坏主意。使用临时指针;不是带有覆盖的列表头。将const单个间接指针传递给这个函数(这是它真正需要的,所以......)会在编译时发现这个错误。无关,我强烈建议不要将局部变量命名为与它们所在的函数相同的名称。 -
你是在做一个二叉搜索树还是一个排序链表,如果它的二叉搜索树你没有在插入中设置右侧节点
-
@Pras 它看起来是一棵二叉搜索树,其节点包含 IP 记录的链表链。
-
顺便说一句,您的搜索功能中的
temp->ipHead = temp->ipHead->ipNext;也存在同样的问题。您可能需要查看有关指针的文本/课程参考。您似乎认为制作指针的副本意味着您可以修改它所指向的内容而不会产生影响。实际上,这意味着您现在拥有 两个 指针,您可以/将通过这些指针修改数据。 -
@WhozCraig Right..显然 bst 是由用户,Anon_Singh 在插入函数中你应该在这里取正确的子树 "else if(strcmp(user, startList->data)>0){startList=startList- >左;}”
标签: c loops pointers linked-list iterator