C语言链表操作

C语言实现链表基本操作 如果把数据比喻成珠子,指针就是线,链表通过指针这条线就是把数据这些珠子串起来。 阅读详情
  • 项目名称
    Link_List

  • 文件

head.h

#ifndef LINK_LIST_HEAD_H
#define LINK_LIST_HEAD_H

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

typedef enum _gender_ {man, women} Gender; // 性别

typedef struct std {
    int          ID;       // ID
    char         name[21]; // 姓名
    Gender       gender;   // 性别
    int          age;      // 年龄
    struct std*  next;     // 下一个节点
} Std;

Std* Link_created(void); // 创造链表
bool Link_input(Std* index_Std); // 输入链表中一个节点的内容
bool Link_output(Std* index_Std); // 输出链表中一个节点的内容
bool Link_input_check(void); // 检查是否继续输入(用于构建和添加)
bool Link_malloc(Std** p, int len); // 向p指针内分配len个节点的内存
Std* Link_search(Std* head, int index_ID); // 根据ID查找节点 若找不到则返回NULL(ID必须唯一)
Std* Link_before(Std* head, int index_ID); // 返回前一节点 若没有则返回NULL
Std* Link_after(Std* head, int index_ID); // 返回后一节点 若没有则返回NULL
bool Link_insert_ID_bef(Std** head, int index_ID); // 在对应ID的节点的前面插入节点
bool Link_insert_ID_aft(Std* head, int index_ID); // 在对应ID的节点的后面插入节点
bool Link_insert_Std_bef(Std** head, Std* index_Std); // 在对应节点的前面插入节点
bool Link_insert_Std_aft(Std* head, Std* index_Std); // 在对应节点的后面插入节点
bool Link_delete_ID(Std** head, int index_ID); // 删除对应ID的节点
bool Link_delete_name(Std** head, char* index_name); // 删除所有具有对应姓名的节点
bool Link_delete_gender(Std** head, Gender index_gender); // 删除所有具有对应性别的节点
bool Link_delete_age(Std** head, int index_age); // 删除所有具有对应年龄的节点
bool Link_delete_Std(Std** head, Std* index_Std); // 删除对应节点
bool Link_free(Std* head); // 释放整个链表的内存
bool Link_add_head(Std** head); // 在链表的头部添加一系列节点
bool Link_add_end(Std* end); // 在链表的尾部添加一系列节点
bool Link_display(Std* head); // 打印链表内容
bool Link_display_name(Std* head); // 打印链表内所有的姓名
bool Link_reversal(Std** head); // 反转链表
int Link_get_ID(Std* index_Std); // 获得节点的ID
char* Link_get_name(Std* index_Std); // 获得节点的姓名
Gender Link_get_gender(Std* index_Std); // 获得节点的性别
int Link_get_age(Std* index_Std); // 获得节点的年龄
bool Link_next(Std** index_Std); // 指向下一个节点
bool Link_arrange_ID(Std* head); // 根据ID排序
bool Link_linked(Std* head, Std* end); // 连接节点
bool Link_swap(Std* a, Std* b); // 交换节点的内容
bool Link_copy_all(Std* dest, Std* src); // 复制节点的所有内容(包含next)
bool Link_copy_value(Std* dest, Std* src); // 复制节点的内容(不包含next)

#endif //LINK_LIST_HEAD_H


main.c

#include "head.h"

int main()
{
#if false
    /* test1 */ {
        Std* test = Link_created();
        printf("\n\nNow input another.\n\n");
        Std* det = Link_created();

        Link_display(test);
        printf("Display end.\n\n");

        while (det != NULL) {
            Link_delete_age(&test, Link_get_age(det));
            det = det->next;
        }

        Link_display(test);
        printf("Display end.\n\n");

        Link_free(test);
    } // 此处测试可演示作业2
    /**
     * 建立一个链表
     * 每个节点包括:学号,姓名,性别以及年龄
     * 输入一个链表
     * 如果链表中的节点所包含的年龄等于此年龄,则将此节点删去
     */
    /**
     * 1.  Created
     * 2.  Malloc
     * 3.  Input
     * 4.  Input Check
     * 5.  Next
     * 6.  Display
     * 7.  Output
     * 8.  Free
     * 9.  Get Age
     * 10. Delete Age
     */
#endif

#if false
    /* test2 */ {
        Std* test = Link_created();

        Link_display(test);
        printf("Display end.\n\n");

        Link_reversal(&test);
        Link_display(test);
        printf("Reversal end.\n\n");

        Link_free(test);
    } // 此处测试可演示作业3
    /**
     * 通过指针将单链表直接倒序
     * (不声明新链表或者数组)
     * (这个题搞懂了,链表这块就没什么大问题了)
     */
    /**
     * 1. Reversal
     */
#endif

#if false
    /* test3 */ {
        Std* test = Link_created();

        Link_display(test);
        printf("Display end.\n\n");

        Std* ret = Link_search(test, 2);
        Link_output(ret);
        printf("Search end.\n\n");

        Std* before = Link_before(test, ret->ID);
        Link_output(before);
        printf("Before end.\n\n");

        Std* after = Link_after(test, ret->ID);
        Link_output(after);
        printf("After end.\n\n");

        Link_arrange_ID(test);
        Link_display(test);
        printf("Arrange end.\n\n");

        Link_free(test);
    }
    /**
     * 1. Search
     * 2. Before
     * 3. After
     * 4. Arrange
     * 5. Copy
     * 6. Swap
     */
#endif

#if false
    /* test4 */ {
        Std* test = Link_created();

        Link_display(test);
        printf("Display end.\n\n");

        Link_delete_ID(&test, 2);
        Link_display(test);
        printf("Delete_ID end.\n\n");

        Link_display_name(test);
        char name[21];
        scanf("%s", name);
        Link_delete_name(&test, name);
        Link_display(test);
        printf("Delete_name end.\n\n");

        Link_delete_gender(&test, 0);
        Link_display(test);
        printf("Delete_gender end.\n\n");

        Link_delete_age(&test, 18);
        Link_display(test);
        printf("Delete_age end.\n\n");

        Link_free(test);
    }
    /**
     * 1. Delete
     * 2. Display Name
     */
#endif

#if false
    /* test5 */ {
        Std* test = NULL;
        Link_malloc(&test, 1);
        Link_input(test);

        printf("----------------\n");
        printf("ID:     %d\n", Link_get_ID(test));
        printf("name:   %s\n", Link_get_name(test));
        if (Link_get_gender(test) == man) {
            printf("gender: man\n");
        }
        else {
            printf("gender: women\n");
        }
        printf("age:    %d\n", Link_get_age(test));
        printf("----------------\n");Link_display(test);

        printf("Get end.\n\n");

        Link_free(test);
    }
    /**
     * 1. Get
     */
#endif

#if false
    /* test6 */ {
        Std* test = Link_created();

        Link_display(test);
        printf("Display end.\n\n");

        Link_insert_ID_aft(test, 1);
        Link_display(test);
        printf("Insert_aft end.\n\n");

        Link_insert_ID_bef(&test, 1);
        Link_display(test);
        printf("Insert_bef end.\n\n");

        Std* ID_2 = Link_search(test, 2);

        Link_insert_Std_aft(test, ID_2);
        Link_display(test);
        printf("Insert_aft end.\n\n");

        Link_insert_Std_bef(&test, ID_2);
        Link_display(test);
        printf("Insert_bef end.\n\n");

        Link_add_head(&test);
        Link_display(test);
        printf("Add_head end.\n\n");

        while (test->next) {
            test = test->next;
        }
        Link_add_end(test);
        Link_display(test);
        printf("Add_end end.\n\n");

        Link_free(test);
    }
    /**
     * 1. Insert
     * 2. Add
     */
#endif

#if false
    /* test7 */ {
        Std* test1 = NULL;
        Link_malloc(&test1, 1);
        Link_input(test1);

        Std* test2 = NULL;
        Link_malloc(&test2, 1);
        Link_input(test2);

        Std* test3 = NULL;
        Link_malloc(&test3, 1);
        Link_input(test2);

        Std* test4 = NULL;
        Link_malloc(&test4, 1);

        Link_linked(test1, test2);
        Link_linked(test2, test3);

        Link_copy_all(test4, test2);
        Link_linked(test1, test4);
        free(test2);

        Link_display(test1);
        printf("Display end.\n\n");

        Link_free(test1);
    }
    /**
     * 1. Linked
     * 2. Copy All
     */
#endif
    return 0;
}

Link_add.c

#include "head.h"

bool Link_add_head(Std** head)
{
    if (*head == NULL) {
        return false;
    } // 若为空链表则返回
    do {
        Std *new = NULL;
        Link_malloc(&new, 1);
        Link_input(new); // 创建新的节点
        new->next = *head; // 链接
        *head = new; // 改变头指针
    } while (Link_input_check()); // 按照输入判断是否继续添加
    return true;
}

bool Link_add_end(Std* end)
{
    if (end == NULL) {
        return false;
    } // 若为空链表则返回
    do {
        Std *new = NULL;
        Link_malloc(&new, 1);
        Link_input(new); // 创建新的节点
        end->next = new; // 链接
        end = new; // 改变尾指针
    } while (Link_input_check()); // 按照输入判断是否继续添加
    return true;
}

Link_after.c

#include "head.h"

Std* Link_after(Std* head, int index_ID)
{
    if (head == NULL) {
        return NULL;
    } // 若为空链表则返回false
    while (head != NULL) {
        if (head->ID == index_ID) {
            return head->next; // 找到则返回该节点
        }
        head = head->next;
    } // 遍历链表
    return NULL; // 找不到则返回NULL
}

Link_arrange.c

#include "head.h"

bool Link_arrange_ID(Std* head)
{
    if (head == NULL) {
        return true;
    }
    Std* i = head;
    while (i->next != NULL) {
        Std* j = i;
        int min_ID = j->ID;
        Std* min = j;
        while (j->next != NULL) {
            if (j->next->ID < min_ID) {
                min_ID = j->next->ID;
                min = j->next;
            }
            j = j->next;
        }
        Link_swap(i, min);
        i = i->next;
    } // 选择排序
    return true;
}

Link_before.c

#include "head.h"

Std* Link_before(Std* head, int index_ID)
{
    if (head == NULL) {
        return NULL;
    } // 若为空链表则返回false
    if (head->ID == index_ID) {
        return NULL;
    } // 若该节点为头节点则返回NULL
    while (head->next != NULL) {
        if (head->next->ID == index_ID) {
            return head; // 找到则返回该节点
        }
        head = head->next;
    } // 遍历链表
    return NULL; // 找不到则返回NULL
}

Link_copy.c

#include "head.h"

bool Link_copy_all(Std* dest, Std* src)
{
    if (dest == NULL || src == NULL) {
        return false;
    }
    dest->ID = src->ID;
    strcpy(dest->name, src->name);
    dest->gender = src->gender;
    dest->age = src->age;
    dest->next = src->next;
    return true;
}

bool Link_copy_value(Std* dest, Std* src)
{
    if (dest == NULL || src == NULL) {
        return false;
    }
    dest->ID = src->ID;
    strcpy(dest->name, src->name);
    dest->gender = src->gender;
    dest->age = src->age;
    return true;
}

Link_created.c

#include "head.h"

Std* Link_created(void)
{
    Std* head = NULL;
    Std* p = NULL;
    Link_malloc(&p, 1);
    Link_input(p); // 先创建头节点
    head = p;
    while (Link_input_check()) {
        Link_malloc(&(p->next), 1);
        Link_next(&p);
        Link_input(p);
    } // 根据输入判断是否继续输入

    return head; // 返回头指针
}

Link_delete.c

#include "head.h"

bool Link_delete_ID(Std** head, int index_ID)
{
    if (*head == NULL) {
        return false;
    } // 若为空链表,返回false
    Std* det = Link_search(*head, index_ID); // 查找对应节点
    if (det == NULL) {
        return false;
    } // 若找不到,返回false
    if ( Link_delete_Std(&(*head), det) ) {
        return true;
    } // 删除成功返回true
    else {
        return false;
    } // 删除失败返回false
}

bool Link_delete_name(Std** head, char* index_name)
{
    if (*head == NULL) {
        return false;
    } // 若为空链表,返回false
    Std* p = *head;
    while (p) { // 遍历链表
        if (strcmp(p->name, index_name) == 0) {
            Link_delete_Std(&(*head), p); // 若相同则删除对应节点
        }
        p = p->next;
    }
    return true;
}

bool Link_delete_gender(Std** head, Gender index_gender)
{
    if (*head == NULL) {
        return false;
    } // 若为空链表,返回false
    Std* p = *head;
    while (p) { // 遍历链表
        if (p->gender == index_gender) {
            Link_delete_Std(&(*head), p); // 若相同则删除对应节点
        }
        p = p->next;
    }
    return true;
}

bool Link_delete_age(Std** head, int index_age)
{
    if (*head == NULL) {
        return false;
    } // 若为空链表,返回false
    Std* p = *head;
    while (p) { // 遍历链表
        if (p->age == index_age) {
            Link_delete_Std(&(*head), p); // 若相同则删除对应节点
        }
        p = p->next;
    }
    return true;
}

bool Link_delete_Std(Std** head, Std* index_Std)
{
    if (*head == NULL) {
        return false;
    } // 若为空链表,返回false
    Std* before = Link_before(*head, index_Std->ID); // 找到链表的前一个节点(前一个节点存在则节点一定存在)
    if (before == NULL) { // 前一个节点为空时
        if ((*head)->ID == index_Std->ID) { // 判断节点是否为头节点
            Std* temp = *head;
            *head = (*head)->next;
            free(temp);
            return true; // 删除头节点
        }
        else {
            return false; // 若不是头节点则返回false(链表中不存在这个节点)
        }
    }
    Std* after = index_Std->next; // 找到链表的后一个节点(此时节点一定存在)
    if (after == NULL) { // 后一个节点为空时(即节点为尾节点)
        before->next = NULL;
        free(index_Std);
        return true; // 删除尾节点
    }
    else {
        before->next = after;
        free(index_Std);
        return true; // 删除中间节点
    }
}

Link_display.c

#include "head.h"

bool Link_display(Std* head)
{
    if (head == NULL) {
        return false;
    } // 若为空链表则返回
    while ( head != NULL ) {
        Link_output(head);
        head = head->next;
    }
    return true;
}

bool Link_display_name(Std* head)
{
    if (head == NULL) {
        return false;
    } // 若为空链表则返回
    printf("----------------\n");
    while (head != NULL) {
        printf("%s\n", head->name);
        head = head->next;
    }
    printf("----------------\n");
    return true;
}

Link_free.c

#include "head.h"

bool Link_free(Std* head)
{
    if (head == NULL) {
        return false;
    } // 若为空链表则返回false
    Std* temp = NULL; // 用于保存节点
    while (head->next) {
        temp = head;
        head = head->next;
        free(temp);
    } // 遍历链表
    free(head);
    return true;
}

Link_get.c

#include "head.h"

int Link_get_ID(Std* index_Std)
{
    return index_Std->ID;
}

char* Link_get_name(Std* index_Std)
{
    return index_Std->name;
}

Gender Link_get_gender(Std* index_Std)
{
    return index_Std->gender;
}

int Link_get_age(Std* index_Std)
{
    return index_Std->age;
}

Link_input.c

#include "head.h"

bool Link_input(Std* index_Std)
{
    if (index_Std == NULL) {
        return false;
    }
    printf("Waiting for your input.\n");
    printf("0 means man and 1 means women.\n");
    printf("----------------\n");

    printf("ID:     ");
    scanf("%d", &(index_Std->ID));

    printf("name:   ");
    scanf("%20s", index_Std->name);

    printf("gender: ");
    int gender;
    scanf("%d", &gender);
    if (gender) {
        index_Std->gender = women;
    } else {
        index_Std->gender = man;
    }

    printf("age:    ");
    scanf("%d", &(index_Std->age));

    index_Std->next = NULL;

    printf("----------------\n");

    return true;
}

bool Link_input_check(void)
{
    getchar();// For get the '\n'
    printf("Continue to input?\n\"q\" to quit and \"c\" to continue.\n");
    char check;
    scanf("%c", &check);
    return (check == 'q')?false:true;
}

Link_insert.c

#include "head.h"

bool Link_insert_ID_bef(Std** head, int index_ID)
{
    if (head == NULL) {
        return false;
    } // 若为空链表,返回false
    Std* before = Link_before(*head, index_ID); // 找到链表的前一个节点(前一个节点存在则节点一定存在)
    if (before == NULL) { // 前一个节点为空时
        if ((*head)->ID == index_ID) { // 判断节点是否为头节点
            Std* new = NULL;
            Link_malloc(&new, 1);
            Link_input(new); // 创建新的节点
            new->next = *head;
            *head = new; // 链接
            return true;
        }
        else {
            return false;
        }
    }
    else { // 找到了前一个节点
        Std* p = before->next; // 后一个节点(即传入的节点)
        Std* new = NULL;
        Link_malloc(&new, 1);
        Link_input(new); // 创建节点
        before->next = new;
        new->next = p; // 链接
        return true;
    }
}

bool Link_insert_ID_aft(Std* head, int index_ID)
{
    if (head == NULL) {
        return false;
    } // 若为空链表,返回false
    Std* p = Link_search(head, index_ID); // 查找对应节点
    if (p == NULL) {
        return false;
    } // 若找不到则返回false
    Std* after = p->next; // 下一个节点
    if (after == NULL) { // 没有下一个节点则节点为尾节点
        Std *new = NULL;
        Link_malloc(&new, 1);
        Link_input(new); // 创建新的节点
        p->next = new; // 链接
        return true;
    }
    else { // 有下一个节点则为中间的节点
        Std *new = NULL;
        Link_malloc(&new, 1);
        Link_input(new); // 创建新的节点
        p->next = new;
        new->next = after; // 链接
        return true;
    }
}

bool Link_insert_Std_bef(Std** head, Std* index_Std)
{
    if (head == NULL || index_Std == NULL) {
        return false;
    } // 若为空链表或空节点则返回false
    Std* before = Link_before(*head, index_Std->ID); // 前一个节点
    if (before == NULL) { // 前一节点为空时
        if (index_Std->ID == (*head)->ID) { // 判断是否为头节点
            Std *new = NULL;
            Link_malloc(&new, 1);
            Link_input(new); // 创建新的节点
            new->next = *head; // 链接
            *head = new; // 改变头指针
            return true;
        }
        else {
            return false; // 不是头节点则返回false(该节点不存在)
        }
    }
    else { // 前一节点不为空时
        Std *new = NULL;
        Link_malloc(&new, 1);
        Link_input(new); // 创建新的节点
        before->next = new;
        new->next = index_Std; // 链接
        return true;
    }
}

bool Link_insert_Std_aft(Std* head, Std* index_Std)
{
    if (head == NULL || index_Std == NULL) {
        return false;
    } // 若为空链表或空节点则返回false
    Std* p = Link_search(head, index_Std->ID); // 查找对应节点
    if (p == NULL) {
        return false;
    } // 若找不到则返回false
    Std* after = index_Std->next; // 后一个节点
    if (after == NULL) { // 若后一个节点为空则为尾节点
        Std *new = NULL;
        Link_malloc(&new, 1);
        Link_input(new); // 创建新节点
        index_Std->next = new; // 链接
        return true;
    }
    else { // 若后一个节点不为空则为中间节点
        Std *new = NULL;
        Link_malloc(&new, 1);
        Link_input(new); // 创建新节点
        index_Std->next = new;
        new->next = after; // 链接
        return true;
    }
}

Link_linked.c

#include "head.h"

bool Link_linked(Std* head, Std* end)
{
    if (head == NULL || end == NULL) {
        return false;
    }
    head->next = end;
    return true;
}

Link_malloc.c

#include "head.h"

bool Link_malloc(Std** p, int len)
{
    if (p == NULL) {
        return false;
    }
    *p = (Std*)malloc(len * sizeof(Std));
    if (*p == NULL) {
        return false;
    }
    else {
        return true;
    }
}

Link_next.c

#include "head.h"

bool Link_next(Std** index_Std)
{
    if (*index_Std == NULL) {
        return false;
    }
    *index_Std = (*index_Std)->next;
    return true;
}

Link_output.c

#include "head.h"

bool Link_output(Std* index_Std)
{
    if (index_Std == NULL) {
        return false;
    }
    printf("----------------\n");
    printf("ID:     %d\n", index_Std->ID);
    printf("name:   %s\n", index_Std->name);
    if (index_Std->gender == man) {
        printf("gender: man\n");
    }
    else {
        printf("gender: women\n");
    }
    printf("age:    %d\n", index_Std->age);
    printf("----------------\n");
    return true;
}

Link_reversal.c

#include "head.h"

bool Link_reversal(Std** head)
{
    if (*head == NULL|| (*head)->next == NULL) {
        return false;
    } // 若为空链表或只有一个节点的链表则返回false(不能反转)
    Std* p = NULL;
    Std* q = NULL;
    Std* r = NULL; // 用于反转的指针
    p = *head;
    q = p->next;
    p->next = NULL; // 头变尾
    while ( q != NULL ) { // 当到末尾时结束循环
        r = q->next;
        q->next = p;
        p = q;
        q = r;
    } // 将后一个节点拆下来链接到前一个节点上
    *head = p; // 改变头节点
    return true;
}

Linkl_search.c

#include "head.h"

Std* Link_search(Std* head, int index_ID)
{
    if (head == NULL) {
        return NULL;
    } // 如果链表为空则返回false
    while (head != NULL) { // 遍历链表
        if (head->ID == index_ID) {
            return head;
        } // 若找到则返回节点
        head = head->next; // 遍历
    }
    return NULL; // 遍历结束(找不到)返回false
}

Link_swap.c

#include "head.h"

bool Link_swap(Std* a, Std* b)
{
    if (a == NULL || b == NULL) {
        return false;
    }
    Std* temp = NULL; // 创建临时节点
    temp = (Std*)malloc(sizeof(Std)); // 分配内存
    Link_copy_value(temp, a);
    Link_copy_value(a, b);
    Link_copy_value(b, temp); // 交换内容
    free(temp); // 释放临时节点的内存
    return true;
}
函数指针的详细解释及应用 函数指针 函数指针在大型的 C 语言项目中十分重要,但是学校对它的介绍一带而过,国内一些介绍函数指针的文章十分粗浅甚至存在错误(这里就不点名了),因此博主写了这篇文章介绍函数指针,希望能够帮助一些 C 语言学习者。 文章部分内容翻译引用于 https://www.geeksforgeeks.org/function-pointer-in-c/ 函数指针的概念 类似变量,函数也会被分配一段存储空间,这段存储空间的首地址即被称做这个函数的地址。而且函数名表示的就是这个地址。既然是地址,我们就可以定义一个指针变量 阅读详情

相关推荐

用C语言实现单链表操作

用C写一个链表 链表(Linked List)是一种非连续的线性数据结构,相对于数组,它允许数据在内存中非连续存储,但是不支持随机读取。 链表 链表由一个个节点(Node)组成,每个节点除了记录数据以外,还需要记录下一个节点的位置(如果是双向链表,还需要记录上一个节点的位置) struct _Node; typedef struct _Node Node; struc...

xuzhougeng blog 7225

C语言链表代码,注释详细

C语言链表代码,注释详细,配套视频讲解如下 看动画学编程 | C语言链表概念详解 /* * C语言版本C99,如果编译器版本过低会无法编译 * 在CodeBlocks和VS2019上测试过 * 看代码遇到问题可以+Q: 1497161158 */ #include <stdio.h> #include <stdlib.h> // 导入库用于调用malloc函数动态分配内存 // 定义链表节点 typedef struct Node { int value; .

cooping 3007

C语言之链表操作

一个节点就是一个结构体变量1,单链表节点//数据域int num;char c;//地址域}Node;2,双链表节点//数据域int num;char c;//地址域}Node;

m0_75253775的博客 1110

C语言 打乱数组

打乱数组 代码 #include <stdio.h> #include <stdlib.h> #include <time.h> void disorganise(int a[], int len); void exchange(int* a, int* b); int main(void) { int a[] = {1,2,3,4,5,6,7,8,...

AimerNeige的博客 4463

c语言链表的基本操作

NULL && curr->data < 20) { // 遍历找到插入位置的前一个节点和插入位置的节点。要在指定位置插入节点,需要先找到插入位置的前一个节点,然后将前一个节点的指针指向新节点,新节点的指针指向下一个节点。

1680

C语言单向链表的各种操作

直接上代码了。// Link.cpp: 定义控制台应用程序的入口点。 // #include "stdafx.h" #include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; //malloc函数 using namespace std; typedef int dataType; typedef struct ListNode { dataTy...

xwm1993的博客 455

C语言——链表的基础操作

摘要:本文系统地介绍了链表数据结构的实现与操作。内容包括链表节点的结构体定义、基本操作函数(创建节点、头插法、尾插法、指定位置插入、按值删除、查找等)以及高级操作(替换元素、链表倒置、打印和清空)。文章通过图示逻辑和代码示例,详细展示了每种操作的实现步骤和内存变化过程。最后提供了一个交互式测试主函数,便于验证各种链表操作。

2501_92642798的博客 1428

C语言链表操作详解

为什么要使用链表 在未学习链表时,我们常用的存储数据的方式无非就是数组。使用数组存储数据的好处就是查询快,但是它的弊端也很明显: 使用前需声明数组的长度,一旦声明长度就不能更改 插入和删除操作需要移动大量的数组元素,效率慢 只能存储一种类型的数据. 而链表则可以实现以上这些数组所不具备的功能,此时引入了结构体来实现创建链表的操作。 链表的特点: n个节点离散分配 每一个节...

qq_41481924的博客 14万+

【C语言】链表操作

为了使链表更加通用和灵活,可以使用自定义数据结构。可以将链表节点的数据定义为一个结构体,这样可以存储更多类型的数据。·引用头文件·自定义数据结构int id;} Word;·链表节点结构体Word data;} Node;·向链表头部添加节点·打印链表= NULL) {·主函数return 0;⬇️过程和上述差不多,只不过变成了一个组(包含ID和word的)

📖在读学生📖 1152

Cadence Allegro 17.4学习记录开始01-原理图Capture CIS 17.4

Orcad的学习记录

qq_31444421的博客 1万+

【可不卸载重装】VS2019新建项目里没有CUDA选项

问题:VS2019 新建项目里没有CUDA选项,vs也属性没有cuda。这是因为你在Visual Studio 2019安装之前,先安装了CUDA Toolkit。

qq_62844901的博客 1321

C语言操作链表详解

C语言操作链表详解链表的概念链表的操作将数据抽象成结构体创建和初始化链表输出链表中存储的数据查找链表中指定位置中存储的数据在链表中插入数据删除指定位置的数据修改制定位置的数据逆序输出链表存储的数据执行结果 在我们学习C语言的前期,每当我们要进行大量数据的读写时,我们都会使用顺序表,也就数组,它的优点很明显,增删读写操作很简单,易于上手。但当我们对数据的存储理解更加深刻时,我们便会逐渐意识到顺序表也不是万能的,它也有它的缺点:顺序表在内存中的存储时,占用一大块连续的空间,但我们实际在使用时,可能并没有那么大的

Violet277的博客 2753

目标检测中的困难样本挖掘:YOLOv5训练效果提升30%的秘诀

本文深入探讨了目标检测中困难样本挖掘的关键技术,特别是如何通过在线困难样本挖掘(OHEM)策略显著提升YOLOv5模型的性能。文章详细解析了困难样本的分类、识别机制及实战配置,并提供了数据标注策略与增强技巧,最终实现模型性能提升30%的突破。

weixin_30379531的博客 402

C语言技能实践之链表的创建与操作

与单独由数组构成的顺序表不同的是,由于链表所具有的指针域,决定了链表可以实现结点之间的地址(所在位置)可以在结构上不相邻,只需在每个结点的数据域后添加地址信息即可通过指针将当前结点与下一结点连接起来,从而形成链表。链表的增加和插入,顾名思义,就是在一个空链表上插入一个新的结点,或是在一个结点与另一个结点之间插入一个新结点,亦或是在链表的尾结点加入一个新结点。值得注意的是,在执行头插法时,指针指向的调整顺序必须遵循以下原则:先将新结点的后继指针指向头结点的后继结点,最后再调整头结点的后继指针指向新结点。

tanjielin2003的博客 1899

如何理解反步法设计控制器?

假设以二阶系统为例,被控对象的系统状态方程为: 基于反步控制的具体方法如下: 1.1步骤一 定义期望状态为xd,状态误差e1,为: e1=x1-xd; 则e1的导数为: 1.2步骤二 定义虚拟控制量为: e2定义为: 1.3步骤三 定义Lyapunov能量函数为: 1.4步骤四 定义总Lyapunov能量函数为: 因此设计的控制律为: 设计c>0,则: 满足Lyapunov的稳定性判定条件...

weixin_42736130的博客 2万+

实战ByteTrack:用C++手把手教你实现多目标跟踪(附完整代码解析)

本文通过C++实战教程,手把手教你实现ByteTrack多目标跟踪算法。文章详细解析了算法核心,包括利用卡尔曼滤波进行状态预测、匈牙利算法完成数据关联,以及ByteTrack独特的三次匹配策略来有效处理低置信度检测框,并提供了完整的项目架构、代码实现与性能优化指南。

yolo5detector的博客 300

单向链表的C语言实现与基本操作

本文的主要内容目录: 一、单向链表的C语言实现 二、单向链表的基本操作 一、单向链表的C语言实现 链表作为一种基本的数据结构在程序开发过程当中经常会使用到。对C语言来说链表的实现主要依靠结构体和指针,所以本文相关内容和程序需要有C语言当中指针和结构体的基础。 链表是一种线性存储数据的结构,存储内容在逻辑上连续的,在物理上却不一定连续。单向链表的组成包括一个链表头(head)和若干

TECH_PRO的博客 5万+

LabVIEW多界面应用开发:从启动器到主界面的切换架构与实现

在图形化编程领域,模块化与界面管理是构建复杂应用程序的核心。其原理在于通过清晰的程序架构,实现不同功能模块间的独立运行与协同工作,从而提升代码的可维护性和可扩展性。这种架构的技术价值在于能够有效管理应用程序的生命周期与资源,避免内存泄漏,并确保流畅的用户体验。在测控系统、自动化测试等工程实践中,常需实现如启动界面选择语言或模式后,无缝切换至主功能界面的场景。本文聚焦于LabVIEW环境,深入探讨如何利用动态调用、状态机等机制,并结合功能全局变量(FGV)与队列消息处理器(QMH)等热词技术,构建健壮的多界面

weixin_30802819的博客 263

【链表】双向链表的基本操作详解(C语言)

本文是单链表的C语言实现方法,包括单链表的创建、插入、删除、修改、查找等基本操作。 双链表是链表中的一种,他和单链表一样都是通过指针将一个个结点连接起来。他和单链表不同的地方在于:单链表的每个结点的指向只有一个,双向链表每个结点有两个指向。 双向链表结点结构体 双向链表每个结点除了存储数据data外,还有两个指针记录上一个结点和下一个结点的地址,分别是前驱指针prev和后继指针next,所以双向链...

HongKnight的博客 2万+

181、LLC谐振变换器的PCB设计实战(文件归档)

PCB设计实战经验总结:LLC谐振变换器的关键要点 本文通过实际案例总结了LLC谐振变换器PCB设计中的核心经验和常见误区。重点包括: 文件命名规范(项目代号_板卡类型_版本号_日期格式) 四层板标准层叠结构设计要点 谐振回路走线原则(宽度、长度控制) 地线处理技巧(功率地/控制地隔离) 散热设计注意事项(MOSFET过孔阵列、变压器布局) 完整的文件归档清单(Gerber、钻孔、装配图等) 作者特别强调,良好的设计归档习惯能显著降低生产问题概率,建议采用双重备份机制。文中多个真实案例(如谐振频率偏移、EM

Jack010169的博客 44

华为OD机试真题 新系统【Skill执行链完整性检测】

华为OD机试 新系统真题【Skill执行链完整性检测】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【Skill执行链完整性检测】

qq_45776114的博客 765

c语言 链表基本操作

当链表不为空时,则需循环遍历链表,找到链表中最后一个结点,然后将其的next域指向新节点,即cur->next=newnode,此时,不需要将新节点的next域赋值为空,因为在创建结点函数中已将next域赋值为空。在进行头插元素的时候,第一步和第二步不能进行交换,如果先进pre->next=s,此时pre->next指向了s,在进行s->next=pre->next,就会使s->next指向自己本身,无法达到预期效果。如果给定位置正常,则直接将给定位置的next指向,给定位置的next的next。...

weixin_63178060的博客 9286

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

C语言的链表操作

链表(Linked List)是一种线性数据结构,由一系列结点(Node)组成。每个结点包含两个部分:存储数据的域和指向下一个结点的指针。通过指针将每个结点连接起来,从而形成链表。

2501_91366480的博客 466

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

用c语言编写链表各种操作,用C语言实现链表的各种操作

#include"stdio.h"#include typedef struct List_Node{int info;struct List_Node *next;}node;//链表长度int Count_Node(node *head){node *p;int num=0;if (head ==NULL){return;}p=head->next;while(p!=NULL){num+...

weixin_31199791的博客 221

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

上一篇: C语言 韩信点兵
下一篇: PAT (Advanced Level) Practice 1001 A+B Format
AimerNeige
博客等级 码龄7年 33粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值