c - LinkedList - C 中的类型 - 访问函数

标签 c data-structures linked-list pass-by-reference

出于教学原因,我目前正在用 C 实现一个 LinkedList。 我快完成了,但现在很挣扎,因为它并没有完全按照预期的方式去做

长话短说,输出不是我对代码的期望 - 现在我在脑子里盘旋着这个问题,有点累了。

这里是整个实现:

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

/********** GLOBALS *******************************/
#define DEBUG 0

/********** STRUCT AND TYPES DEFINTIONS ***********/
/* a node with key, data and reference to next node*/
typedef struct Node {
    int key;
    char string[1024];
    struct Node *next;  // pointer to next node
} Node;

/* the actual linked list: ref to first and last Node, size attribute */
typedef struct LinkedList {
    struct Node *first;
    struct Node *last;
    int size;
} LinkedList;

/********** FUNCTION HEADERS **********************/
LinkedList init_list();
void insert_end(LinkedList *list, int key, char string[]);
void insert_beginning(LinkedList *list, int key, char string[]);
int remove_end(LinkedList *list);
int remove_beginning(LinkedList *list);
int print_list(LinkedList *list);
void free_list(LinkedList *list);
char * get_string(LinkedList *list, int key);

/*********** FUNCTION DEFINITIONS ***************/
/* init_list Returns an appropriately (for an empty list) initialized struct List*/
LinkedList init_list() {

    if(DEBUG)
        printf("%s:%d called \n", __FUNCTION__, __LINE__);

    LinkedList list;

    list.first = NULL;
    list.last = NULL;
    list.size = 0;

    return list;
}

/* Given a List, a key and a string adds a Node containing this
information at the end of the list*/
void insert_end(LinkedList *list, int key, char string[]) {

    if(DEBUG)
        printf("%s:%d called \n", __FUNCTION__, __LINE__);

    list->size++;                    // increment size of list

    // intialize the new Node
    Node* newN = malloc(sizeof(Node));
    newN->key = key;
    strcpy(newN->string, string);
    newN->next = NULL;

    Node* oldLast = list->last;      // get the old last
    oldLast->next = newN;          // make new Node the next Node for oldlast
    list->last = newN;              // set the new last  in the list

    printf("new Node at end: %d %s %p \n", newN->key, newN->string, newN->next);

}

/* Given a List, a key and a string adds a Node, containing
this information at the beginning of the list */
void insert_beginning(LinkedList *list, int key, char string[]) {

    if(DEBUG)
        printf("%s:%d called \n", __FUNCTION__, __LINE__);

    list->size++;                    // increment size of list
    Node* oldFirst = list->first;    //get the old first node

    // intialize the new Node
    Node* newN = malloc(sizeof(Node));
    newN->key = key;
    strcpy(newN->string,string);
    newN->next = oldFirst;

    list->first = newN;              // set the new first

    //special case: if list size == 1, then this new one is also the last one
    if(list->size == 1)
        list->last = newN;

    printf("new Node at beginning: '%d' '%s' '%p' \n", newN->key, newN->string, newN->next);

}

/* Removes the first Node from the list*/
int remove_beginning(LinkedList *list) {

    if(DEBUG)
        printf("%s:%d called \n", __FUNCTION__, __LINE__);

    if(list->size <= 0)
       return -1;

    list->size--;

    Node * oldFirst = list->first;
    list->first = oldFirst->next;
    oldFirst = NULL;

    return 0;

}

/* Removes the last Node from the list.*/
int remove_end(LinkedList *list) {

    if(DEBUG)
        printf("%s:%d called \n", __FUNCTION__, __LINE__);

    if(list->size <= 0)
        return -1;

    list->size--;                    // decrement list size
    //Node * oldLast = list->last;     // get ref to old last
    //oldLast = NULL;                  // set it null
    //free(oldLast);
    Node * startNode = list->first;
    list->last = NULL;               // set listref last to null

    //find the now new last node..
   Node * newLast = NULL;
   while(startNode->next != NULL) {
        newLast=startNode;
   }

    // if list is not empty now..
    if(list->size > 0)
        list->last = newLast;

    return 0;

}

/* Given a List prints all key/string pairs contained in the list to
the screen*/
int print_list(LinkedList *list) {

    if(DEBUG)
        printf("%s:%d called \n", __FUNCTION__, __LINE__);


    if(list->size <=0)
        return -1;

    printf("List.size = %d \n", list->size);

    Node *startN = list->first;  //get first

    printf("Node#%d.string = '%s', .next = '%d' \n",list->first->key, list->first->string, list->first->next->key);

    //iterate through list
    while(startN->next != NULL) {
        printf("Node#%d.string = '%s', .next = '%d' \n",startN->key, startN->string, startN->next->key);
        startN = startN->next;
    }

    return 0;
}

/* Given a List, frees all memory associated with this list. */
void free_list(LinkedList *list) {

    if(DEBUG)
        printf("%s:%d called \n", __FUNCTION__, __LINE__);

    if(list != NULL)
        free(list);
}

/* Given a List and a key, iterates through the whole List and returns
the string of the first node which contains the key */
char * get_string(LinkedList *list, int key) {

    if(DEBUG)
        printf("%s:%d called \n", __FUNCTION__, __LINE__);

     Node *startN = list->first;  //get first

    //iterate through list
    while(startN->next != NULL) {
        if(startN->key == key)
            return startN->string;
        else
            startN = startN->next;
    }

    return NULL;

}

/*************** MAIN **************/
int main(void)
{

    LinkedList list = init_list();

    insert_beginning(&list, 1,"im the first" );
    insert_beginning(&list, 2,"im the second" );
    insert_beginning(&list, 3,"im the third" );
    //insert_end(&list, 2, "im the second");
    //insert_end(&list, 3,"im the third");
    //insert_end(&list, 4, "forth here");
    //insert_end(&list, 5, "...and i am last");
    //insert_end(&list, 6, "END");

    print_list(&list);

   // remove_end(&list);
   // remove_beginning(&list);

   // print_list(&list);

   // free_list(&list);

}

这是输出,与预期不同(但代码编译正常):

new Node at beginning: '1' 'im the first' '00000000' 
new Node at beginning: '2' 'im the second' '00762EF8' 
new Node at beginning: '3' 'im the third' '00764330' 
List.size = 3 
Node#3.string = 'im the third', .next = '2' 
Node#3.string = 'im the third', .next = '2' 
Node#2.string = 'im the second', .next = '1' 

如您所见,print_list 要么没有正确打印列表,要么列表本身不正确。

  • 我哪里失败了?

一如既往,非常欢迎最佳实践提示,来源是公共(public)领域。

最佳答案

您的队列实际上是一个堆栈,因为您按照先到后出的顺序将内容推到头部。

我只是按如下方式更改了您的 print_list 函数;

//iterate through list
do {
    printf("Node#%d.string = '%s', .next = '%p' \n",startN->key, startN->string, startN->next);
    startN = startN->next;
}while(startN != NULL);

我通过此更改获得的输出是;

new Node at beginning: '1' 'im the first' '0x0'
new Node at beginning: '2' 'im the second' '0x2003ac40'
new Node at beginning: '3' 'im the third' '0x2004b088'
List.size = 3
Node#3.string = 'im the third', .next = '0x2004b088'
Node#2.string = 'im the second', .next = '0x2003ac40'
Node#1.string = 'im the first', .next = '0x0'

关于c - LinkedList - C 中的类型 - 访问函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44115777/

相关文章:

java - 将士兵分配到房间的算法问题

Java awt 为什么我只能删除链表中最近添加的内容

C 指针总和 "not working"

c - 不同机器的运行时间?

c - 开源文本到语音库

java - 这个函数(for 循环)空间复杂度是 O(1) 还是 O(n)?

c - 在 switch block 中声明的变量

嵌套数字列表的 C++ 数据结构

c - 实现内核的链表接口(interface)时出错

c# - 理解链表