双链表搜索函数的C语言实现

双链表搜索函数的C语言实现,c,doubly-linked-list,cs50,C,Doubly Linked List,Cs50,我正在根据CS50 Mooc的指令实现数据结构。我在运行程序时遇到了这个问题 双链接列表。c:71:22:运行时错误:在类型为“dllnode”(也称为“struct dllist”)的空指针内访问成员 分段故障 我们非常感谢您提供的任何建议,以及关于实现其余部分的其他建议 /* Doubly Linked List implementation */ #include <stdio.h> #include <stdlib.h> #include <stdbool

我正在根据CS50 Mooc的指令实现数据结构。我在运行程序时遇到了这个问题

双链接列表。c:71:22:运行时错误:在类型为“dllnode”(也称为“struct dllist”)的空指针内访问成员 分段故障


我们非常感谢您提供的任何建议,以及关于实现其余部分的其他建议

/* Doubly Linked List implementation */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct dllist
{
    int number;
    struct dllist* prev;
    struct dllist* next;
}
dllnode;

/*
The operations needed to work with linked lists
    1. Create a linked list when it doesn't already exist.
    2. Search though a list to find an element.
    3. Insert a new node into the list.
    4. Delete a single element from a linked list.
    5. Delete an entire linked list.
*/

// initialize functions
dllnode *create(int value);
bool find(dllnode *head, int value);
dllnode *insert(dllnode *head, int value);
void delete(dllnode *target);
void destroy(dllnode* head);

dllnode *head_node1; // global variable - pointer to head node.

int main(void)
{
    // create the head which is just a pointer to a linked list that does not yet exsist
    head_node1 = NULL;

    // use linear search function
    bool isFound = find(head_node1, 5);
    printf("%s", isFound ? "true" : "false");
}

// defining function for creating a doubly-linked list
dllnode *create(int value)
{
    // dynamically allocate space for a new dllnode
    dllnode *newNode = malloc(sizeof(dllnode));
    // check to make sure we didn't run out of memory
    if (newNode == NULL)
    {
        fprintf(stderr, "out of memory\n");
        return NULL;
    }
    // initialize the node's value field
    newNode->number = value;
    // initialize the node's prev field
    newNode->prev = NULL;
    // initialize the node's next field
    newNode->next = NULL;
    // return a pointer to the newly created dllnode
    return newNode;
}

// defining a function to search though a linked list to find an element
bool find(dllnode *head, int value)
{
    // create a traversal pointer pointing to the list's head
    dllnode *trav_ptr = head;

    // execute until you reach the end of the list where trav_ptr == NULL
    while (trav_ptr->next != NULL)
    {
        if (trav_ptr->number == value)
        {
            return true;    
        }
        // if not, set the tranversal pointer to the next pointer in the list and go back to prev step
        else 
        {
            trav_ptr = trav_ptr->next;
        }
    }
    // if you've reached the end of list, report failure 
    return false;
}

// defining a function to insert a node into the linked list
dllnode *insert(dllnode *head, int value)
{
    // dynamically allocate space for a new dllnode
    dllnode *newNode = malloc(sizeof(dllnode));
    // check to make sure we didn't run out of memory
    if (newNode == NULL)
    {
        fprintf(stderr, "out of memory\n");
        return NULL;
    }
    // populate and insert the node at the beginning of the linked list
    newNode = create(value);
    newNode->next = head;
    // fix the prev pointer of the old head of the linked list
    head->prev = newNode;
    // return a pointer to the new head of the linked list
    head = newNode;
    return head;
}

// deleting a node from a linked list
void delete(dllnode *target)
{
    // three scenarios, deleting head, middle, or last element

    // if first element
    if (target->prev == NULL)
    {
        // fix the prev pointer of the next element
        target->next->prev = NULL;
        // set head to point to new first element
        head_node1 = target->next;
        // free target
        free(target);
    }
    // if last element
    else if (target->next == NULL)
    {
        // fix the next pointer of the previous element
        target->prev->next = NULL;
        // free target
        free(target);
    }
    // if middle element
    else
    {
        // fix the pointers of the surrounding nodes to "skip over" target
        target->prev->next = target->next;
        target->next->prev = target->prev;
        // free target
        free(target);
    }
}

// delete an entire linked list
void destroy(dllnode* head)
{
    // if you have reached a null pointer, stop
    while (head != NULL)
    {
        // delete the rest of the list
        destroy(head->next);
    }
    // free the current node
    free(head);
}
/*双链表实现*/
#包括
#包括
#包括
类型定义结构dllist
{
整数;
结构dllist*prev;
结构dllist*下一步;
}
dllnode;
/*
使用链接列表所需的操作
1.当链表不存在时创建一个链表。
2.在列表中搜索以查找元素。
3.在列表中插入新节点。
4.从链接列表中删除单个元素。
5.删除整个链接列表。
*/
//初始化函数
dllnode*创建(int值);
布尔查找(dllnode*head,int值);
dllnode*插入(dllnode*头,int值);
作废删除(dllnode*目标);
空洞破坏(dllnode*头部);
dllnode*头节点1;//全局变量-指向头节点的指针。
内部主(空)
{
//创建头,它只是指向尚未存在的链表的指针
头节点1=空;
//使用线性搜索函数
bool isFound=find(头节点1,5);
printf(“%s”,isFound?“true”:“false”);
}
//定义用于创建双链接列表的函数
dllnode*创建(int值)
{
//为新的dllnode动态分配空间
dllnode*newNode=malloc(sizeof(dllnode));
//检查以确保我们没有耗尽内存
if(newNode==NULL)
{
fprintf(stderr,“内存不足”);
返回NULL;
}
//初始化节点的值字段
新建节点->编号=值;
//初始化节点的prev字段
newNode->prev=NULL;
//初始化节点的下一个字段
newNode->next=NULL;
//返回指向新创建的dllnode的指针
返回newNode;
}
//定义一个函数来搜索链接列表以查找元素
布尔查找(dllnode*head,int值)
{
//创建指向列表头的遍历指针
dllnode*trav_ptr=头部;
//执行,直到到达trav_ptr==NULL的列表末尾
while(trav_ptr->next!=NULL)
{
如果(trav_ptr->number==值)
{
返回true;
}
//如果没有,请将Transversal指针设置为列表中的下一个指针,然后返回上一步
其他的
{
trav_ptr=trav_ptr->next;
}
}
//如果您已到达列表的末尾,请报告失败
返回false;
}
//定义将节点插入链接列表的函数
dllnode*插入(dllnode*头,int值)
{
//为新的dllnode动态分配空间
dllnode*newNode=malloc(sizeof(dllnode));
//检查以确保我们没有耗尽内存
if(newNode==NULL)
{
fprintf(stderr,“内存不足”);
返回NULL;
}
//在链表的开头填充并插入节点
newNode=创建(值);
新建节点->下一步=头部;
//修复链接列表旧标题的prev指针
head->prev=newNode;
//返回指向链接列表新标题的指针
头=新节点;
回流头;
}
//从链接列表中删除节点
无效删除(dllnode*目标)
{
//三种方案,删除头、中间或最后一个元素
//如果第一个元素
如果(目标->上一个==NULL)
{
//修复下一个元素的上一个指针
目标->下一步->上一步=空;
//将head设置为指向新的第一个元素
head_node1=目标->下一步;
//自由目标
自由(目标);
}
//如果最后一个元素
else if(目标->下一步==NULL)
{
//修复上一个元素的下一个指针
target->prev->next=NULL;
//自由目标
自由(目标);
}
//if中间元素
其他的
{
//修复周围节点的指针以“跳过”目标
目标->上一步->下一步=目标->下一步;
目标->下一步->上一步=目标->上一步;
//自由目标
自由(目标);
}
}
//删除整个链接列表
无效销毁(dllnode*头)
{
//如果已到达空指针,请停止
while(head!=NULL)
{
//删除列表的其余部分
销毁(头->下一步);
}
//释放当前节点
自由(头);
}

有一个简单的错误。在
find
函数开始时,必须检查
head==NULL
(或
trav\u ptr==NULL
)。在这种情况下,您必须返回'false',因为列表为空。我给你写几行:

bool find(dllnode *head, int value)
{
    dllnode *trav_ptr = head;
    if (trav_ptr == NULL)
        return false;
    ...

“任何建议都将受到高度赞赏”。您将得到的最佳建议是使用调试器。
任何建议都将受到高度赞赏。学习调试(使用printfs或调试器)2。不要取消对空指针的引用。
while(trav\u ptr->next!=NULL)
-->
while(trav\u ptr!=NULL)