C语言链表使用

目录

  • 双链表增删改查
  • 链表带功能函数
  • 链表函数返回值
  • 追加多个

双链表增删改查

#include 
#include 

// 双链表结点的定义
typedef struct DNode{
    int data;
    struct DNode *prev;
    struct DNode *next;
} DNode;

// 创建双链表
DNode *createDoublyLinkedList() {
    int n, i;
    printf("请输入双链表的长度:");
    scanf("%d", &n);

    if (n <= 0) {
        printf("输入的长度无效!\n");
        return NULL;
    }

    DNode *head = NULL;  // 双链表的头结点
    DNode *tail = NULL;  // 双链表的尾结点

    // 创建双链表的结点
    for (i = 0; i < n; i++) {
        int data;
        printf("请输入第 %d 个结点的数据:", i+1);
        scanf("%d", &data);

        DNode *newNode = (DNode*)malloc(sizeof(DNode));
        newNode->data = data;
        newNode->prev = NULL;
        newNode->next = NULL;

        if (head == NULL) {
            head = newNode;
            tail = newNode;
        } else {
            tail->next = newNode;
            newNode->prev = tail;
            tail = newNode;
        }
    }

    return head;
}

// 遍历双链表
void traverseDoublyLinkedList(DNode *head) {
    if (head == NULL) {
        printf("双链表为空!\n");
        return;
    }

    DNode *current = head;

    printf("双链表的数据为:");
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}

// 在指定位置插入结点
void insertNode(DNode **head, int position, int data) {
    if (*head == NULL) {
        printf("双链表为空!\n");
        return;
    }

    DNode *current = *head;
    int currentPosition = 1;

    // 找到指定位置的结点
    while (currentPosition < position && current->next != NULL) {
        current = current->next;
        currentPosition++;
    }

    if (currentPosition < position) {
        printf("插入位置无效!\n");
        return;
    }

    // 创建新结点
    DNode *newNode = (DNode*)malloc(sizeof(DNode));
    newNode->data = data;
    newNode->prev = NULL;
    newNode->next = NULL;

    if (currentPosition == 1) {
        newNode->next = *head;
        (*head)->prev = newNode;
        *head = newNode;
    } else {
        newNode->next = current;
        newNode->prev = current->prev;
        current->prev->next = newNode;
        current->prev = newNode;
    }

    printf("成功插入结点!\n");
}

// 删除指定位置的结点
void deleteNode(DNode **head, int position) {
    if (*head == NULL) {
        printf("双链表为空!\n");
        return;
    }

    DNode *current = *head;
    int currentPosition = 1;

    // 找到指定位置的结点
    while (currentPosition < position && current != NULL) {
        current = current->next;
        currentPosition++;
    }

    if (current == NULL) {
        printf("删除位置无效!\n");
        return;
    }

    if (currentPosition == 1) {
        *head = (*head)->next;
        if (*head != NULL) {
            (*head)->prev = NULL;
        }
    } else {
        current->prev->next = current->next;
        if (current->next != NULL) {
            current->next->prev = current->prev;
        }
    }

    free(current);
    printf("成功删除结点!\n");
}

// 按值查找结点
DNode *searchNode(DNode *head, int data) {
    if (head == NULL) {
        printf("双链表为空!\n");
        return NULL;
    }

    DNode *current = head;

    // 遍历双链表,找到指定值的结点
    while (current != NULL) {
        if (current->data == data) {
            return current;
        }
        current = current->next;
    }

    printf("未找到指定结点!\n");
    return NULL;
}

//获取指定位置数据
int get_node_value(DNode* head, int pos) {
    if (head == NULL) {  // 判断链表是否为空
        printf("链表为空,无法查找!\n");
        return -1;
    }
    int count = 0;
    DNode* current = head;
    while (current != NULL) {
        if (count == pos) {
            return current->data;  // 找到指定位置的节点,返回节点的值
        }
        count++;
        current = current->next;  // 继续遍历下一个节点
    }
    printf("指定位置不存在节点!\n");  // 遍历完整个链表仍然没有找到节点
    return -1;
}

//查看节点数量
int get_node_count(DNode* head) {
    int count = 0;
    DNode* current = head;

    while (current != NULL) {
        count++;
        current = current->next;
    }

    return count;
}

//打印链表数据
void print_list(DNode* head) {
    DNode* current = head;

    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}

//从尾部添加数据
DNode* create_node(int data) {
    DNode* newNode = (DNode*)malloc(sizeof(DNode));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}
void append_node(DNode** head, int data) {
    DNode* newNode = create_node(data);

    if (*head == NULL) {
        // 如果链表为空,则将新节点作为头节点
        *head = newNode;
    } else {
        // 找到链表的末尾节点
        DNode* current = *head;
        while (current->next != NULL) {
            current = current->next;
        }
        // 将新节点添加到末尾
        current->next = newNode;
    }
}

// 释放双链表的内存
void freeDoublyLinkedList(DNode **head) {
    DNode *current = *head;

    while (current != NULL) {
        DNode *temp = current;
        current = current->next;
        free(temp);
    }

    *head = NULL;
    printf("成功释放双链表的内存!\n");
}

int main() {
    DNode *head = NULL;

    // 创建双链表
    head = createDoublyLinkedList();

    // 遍历双链表
    traverseDoublyLinkedList(head);

    // 在指定位置插入结点
    int insertPosition, insertData;
    printf("请输入要插入的位置和数据(以空格分隔):");
    scanf("%d %d", &insertPosition, &insertData);
    insertNode(&head, insertPosition, insertData);
    traverseDoublyLinkedList(head);

    // 删除指定位置的结点
    int deletePosition;
    printf("请输入要删除的位置:");
    scanf("%d", &deletePosition);
    deleteNode(&head, deletePosition);
    traverseDoublyLinkedList(head);

    // 按值查找结点
    int searchData;
    printf("请输入要查找的值:");
    scanf("%d", &searchData);
    DNode *searchResult = searchNode(head, searchData);
    if (searchResult != NULL) {
        printf("成功找到结点!");
    }
    
     int position;
    printf("请输入要查找的位置:");
    scanf("%d", &position);

    int value = get_node_value(head, position);

    if (value == -1) {
        printf("位置超出链表范围!\n");
    } else {
        printf("位置 %d 的值为:%d\n", position, value);
    }   
    
    int count = get_node_count(head);

    printf("链表中共有 %d 个数据节点\n", count);
    
    append_node(&head, 30);
    print_list(head);
    // 释放双链表的内存
    freeDoublyLinkedList(&head);

    return 0;
}

链表带功能函数

#include 
#include 

typedef struct DNode {
    int data;
    void (*Function)(const char*);
    struct DNode* prev;
    struct DNode* next;
} DNode;

// 创建节点
DNode* createNode(int data, void (*function)(const char*)) {
    DNode* node = (DNode*)malloc(sizeof(DNode));
    node->data = data;
    node->Function = function;
    node->prev = NULL;
    node->next = NULL;
    return node;
}

// 插入节点到链表末尾
void insertNode(DNode** head, DNode* node) {
    if (*head == NULL) {
        *head = node;
    } else {
        DNode* current = *head;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = node;
        node->prev = current;
    }
}

// 执行链表中的节点功能函数
void executeListFunction(DNode* head, const char* param) {
    DNode* current = head;
    while (current != NULL) {
        if (current->Function != NULL) {
            current->Function(param);
        }
        current = current->next;
    }
}

/*
遍历链表的所有参数
执行对应的功能函数
*/
void executeListFunctions(DNode* head, int searchData, const char* param) {
    DNode* current = head;
    while (current != NULL) {
        if (current->data == searchData && current->Function != NULL) {
            current->Function(param);
        }
        current = current->next;
    }
}
// 示例的功能函数
void function1(const char* param) {
    printf("执行功能函数1,参数:%s\n", param);
}

void function2(const char* param) {
    printf("执行功能函数2,参数:%s\n", param);
}

int main() {
    // 创建节点,并绑定对应功能函数
    DNode* node1 = createNode(1, function1);
    DNode* node2 = createNode(2, function2);

    // 构建链表
    DNode* head = NULL;
    insertNode(&head, node1);
    insertNode(&head, node2);

    // 执行链表中的功能函数
    executeListFunctions(head, 2, "输入字符串参数");

    // 释放内存
    free(node1);
    free(node2);

    return 0;
}

链表函数返回值

要让 executeListFunction 函数返回 Function(param) 函数的返回值,你可以将其结果存储在一个变量中,并在函数结束时将其返回。

以下是修改后的 executeListFunction 函数:

char* executeListFunction(Button* head, const char* buttonname, const char* param) {
    Button* current = head;
    char* result = NULL;
    while (current != NULL) {
        if (strcmp(current->buttonname, buttonname) == 0 && current->Function != NULL) {
            result = current->Function(param);
        }
        current = current->next;
    }
    return result;
}

我们新增了一个变量 result 来存储 Function(param) 函数的返回值,在循环过程中,当找到对应的节点且其功能函数不为空时,我们调用该功能函数并将其返回值赋值给变量 result。最后,在函数结束时将 result 返回。

接下来,你可以在 main 函数中调用 executeListFunction 函数,并将其返回值输出。示例如下:

char* Function(const char* param) {
    // 计算字符串长度
    int len = strlen(param);
    
    // 分配对应长度的内存空间
    char* result = malloc((len + 1) * sizeof(char));
    
    // 将字符串转换为大写字母
    for (int i = 0; i < len; i++) {
        result[i] = toupper(param[i]);
    }
    
    // 在字符串末尾添加终止符
    result[len] = '\0';
    
    // 返回结果字符串
    return result;
}
// 执行链表中特定按钮名称的功能函数,并返回其返回值
char* executeButtonFunction(Button* head, const char* buttonname, const char* param) {
    return executeListFunction(head, buttonname, param);
}

int main() {
    // 创建链表头节点
    Button* head = createNode(1, 1, 1, "Button 1", exampleFunction);
    
    // 在链表尾部插入节点
    Button* node2 = createNode(2, 1, 2, "Button 2", exampleFunction);
    insertNode(&head, node2);
    
    Button* node3 = createNode(3, 2, 1, "Button 3", exampleFunction);
    insertNode(&head, node3);
    
    // 执行特定按钮名称的功能函数,并输出其返回值
    char* result = executeButtonFunction(head, "Button 1", "Hello World");
    printf("Result: %s\n", result);
    
    return 0;
}

在这个示例中,我们修改了 executeButtonFunction 函数,使其调用新增的 executeListFunction 函数,并将其返回值直接返回。在 main 函数中,我们调用 executeButtonFunction 来执行名为 “Button 1” 的按钮的功能函数,并输出其返回值。

追加多个

以下是一个完整的C代码示例,用于创建一个Button节点数组,将其追加到链表中,并进行函数调用。

#include 
#include 

typedef struct Button {
    int id;
    int type;
    int index;
    char label[20];
    void (*callback)();
    struct Button* next;
} Button;

void exampleFunction() {
    printf("Button has been clicked!\n");
}

Button* createButton(int id, int type, int index, char* label, void (*callback)()) {
    Button* button = (Button*)malloc(sizeof(Button));
    button->id = id;
    button->type = type;
    button->index = index;
    strncpy(button->label, label, sizeof(button->label) - 1);
    button->label[sizeof(button->label) - 1] = '\0';
    button->callback = callback;
    button->next = NULL;
    return button;
}

void appendButton(Button** head, Button* newButton) {
    if (*head == NULL) {
        *head = newButton;
    } else {
        Button* curr = *head;
        while (curr->next != NULL) {
            curr = curr->next;
        }
        curr->next = newButton;
    }
}

int main() {
    Button* head = NULL;

    // 创建新的Button节点数组,用于示例
    Button buttons[] = {
        {1, 0, 1, "chuanshumoshi", exampleFunction},
        {2, 0, 2, "chuanshusudu", exampleFunction},
        {3, 0, 3, "duandianxuchu", exampleFunction},
        {4, 0, 4, "shezhi", exampleFunction},
        {5, 0, 5, "example5", exampleFunction}
    };

    int numButtons = sizeof(buttons) / sizeof(buttons[0]);

    // 追加多个Button到链表末尾
    for (int i = 0; i < numButtons; i++) {
        appendButton(&head, &buttons[i]);
    }

    // 遍历链表并调用按钮回调函数
    Button* curr = head;
    while (curr != NULL) {
        curr->callback();
        curr = curr->next;
    }

    return 0;
}

在这个示例中,我们使用了C语言来创建Button结构体,并定义了createButton函数用于创建新的Button节点。我们还定义了appendButton函数来将新的Button节点追加到链表末尾。

在主函数中,我们创建了一个Button指针head来表示链表的头部。然后,通过迭代数组并调用appendButton函数将每个Button节点添加到链表中。

最后,我们遍历链表并调用每个按钮节点的回调函数。

希望这个完整的代码示例对你有所帮助!如有任何疑问,请随时提问。

你可能感兴趣的:(C语言,c语言,链表,数据结构)