【问题标题】:C linked list search function [closed]C链表搜索功能
【发布时间】:2010-09-25 03:18:04
【问题描述】:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

/*Define custom functions */
void insertElement();
bool elementExists();
int getNumElements();


/*Create linked list */
struct node {
    int number;
    int occurence;
    struct node *next;
};

/*Call our linked list freqTable */
struct node *freqTable = NULL;

unsigned int numElements = 0;

int main(){
    int readNumElements = 0;
    int i = 0;
    int newNum, status;

    status = scanf("%d", &readNumElements);
    if(status == -1){
        fprintf(stderr, "%d is not a number\n", readNumElements);
        exit(-1);
    }


    for (i = 0; i < readNumElements;i++) {
        status = scanf("%d", &newNum);
        if(status == -1){
            fprintf(stderr, "%d is not a number\n", newNum);
            exit(-1);
        }
        if(elementExists(newNum)){
            printf("%d exists\n", newNum);
        }else{
            insertElement(&freqTable, newNum);
        }

    }

return 0;
}

void insertElement(struct node **list, int n){
    struct node *new_input; 

    new_input = malloc(sizeof(struct node));

    if(new_input == NULL){
        fprintf(stderr,"Error: Failed to create memory for new node\n");
        exit(EXIT_FAILURE);
    }

    new_input->number = n;
    new_input->occurence = 1;
    new_input->next = *list;
    numElements++;

    *list = new_input;
}

bool elementExists(int n){
    printf("%d\n", freqTable->number);
return false;
}

int getNumElements(){
    return numElements;
}

好的,这就是我得到的。这应该可以编译。

问题来了

    if(elementExists(newNum)){
        printf("%d exists\n", newNum);
    }else{
        insertElement(&freqTable, newNum);
    }

我得到分段错误,我不知道为什么。

【问题讨论】:

  • 剩下的代码在哪里?
  • 如果您从不分配节点并将其分配给freqTable 变量,您将始终访问内存位置 0 + 一些偏移量,从而保证分段错误!
  • 我建议您发布最短的代码,应该编译和工作但会产生错误。
  • 我认为您在此过程中删除了问题。
  • @Matt:如果你的问题得到了解决,你不需要删除程序 :) 我已经回滚了更改。

标签: c search linked-list


【解决方案1】:

在函数elementExists中需要确保freqTable不是NULL

bool elementExists(int n){
 if(freqTable) {  // add this check
   printf("%d\n", freqTable->number);
 }
}

另外你的elementExists 没有做它应该做的事情(检查是否存在一个值为n 的节点),你应该这样做:

bool elementExists(int n) {

 if(!freqTale) { // table does not exist..return false.
  return false;
 }
 // table exists..iterate node by node and check.
 struct node *tmp = freqTable;
 while(tmp) { // loop till tmp becomes NULL
  if(*tmp == n) { // it node contains n..return false.
    return true;
   }
  tmp = tmp->next; // move on
 }
 return false; // n does not exist in the list..return false.
}

【讨论】:

  • 谢谢,但我发现了错误。希望这会对其他人有所帮助。结构节点 *tmp = freqTable;我基本上做了 struct node *tmp = &freqTable;
【解决方案2】:

调用elementExists有问题:

if(elementExists(&freqTable, newNum)){

您传递freqTable 的地址(即指向存储列表第一个元素的指针的指针)而不是其值。然而在elementExists 中,您取消引用参数,就好像它是指向列表元素的指针:

printf("Compare with: %d\n", list->number);

else list = list->next;

从对elementExists 的调用中删除&amp;。如果您将列表作为参数传递,请勿在 elementExists 内引用全局 freqTable

【讨论】:

  • 是的,在 codaddicts 发布后注意到了这一点。谢谢。这正是我遇到的问题。现在一切都好。
【解决方案3】:

按照 cmets 中的建议,在分配任何节点之前,您将在 elementExists 中取消引用 freqTable。因此,freqTable 始终为 NULL,因此您调用未定义的行为。您可以在 elementExists 中添加一个 NULL 检查,并在这种情况下返回 false。

【讨论】:

  • 你的正确。让我将其更新为我想做的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
  • 2016-01-26
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
  • 2017-07-14
  • 2011-06-24
相关资源
最近更新 更多