C/C++ 链表构建、遍历

本文深入探讨了链表的基本概念,包括链表的构建、遍历和查询操作。介绍了无头链表和有头链表的区别,以及如何在链表中添加元素。通过实例演示了链表的遍历过程和查找特定ID的方法。

1、链表的概述、简单构建、遍历(无头链表)

#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义一个用户对象
struct User
{
    int id;
    char name[20];
    User* next;
};
// 准备四个User对象
User us[4] = {
    {1, "张三", 0},
    {2, "李四", 0},
    {3, "王五", 0},
    {4, "赵六", 0},
};
// 查找链表中ID为1的对象
User* find(User* head, int id);

/*
 链表:
    1、什么是链表?
        把若干个对象用指针连起来,形成一个链状的数据结构,成为链表
    2、特征
        链表头:指链表中的第一个对象。只需要一个链表头,就能访问所有的串起来的对象
        链表尾:指链表中的最后一个对象。 它的next必须设为空指针NULL
    3、链表的遍历:下面while示列
*/
int main() {

    // 简单构建链表(有点类似像Java set赋值child子节点构成树结构数据)
    us[0].next = &us[1];
    us[1].next = &us[2];
    us[2].next = &us[3];
    us[3].next = 0;
    // 链表的最后一个对象的next为Null,也就是0空指针,后面根据这一特征可以判断链表已结束

    // 链表的遍历/循环
    User* p = &us[0];

    printf("ID \t Name\n");
    while (true)
    {
        printf("%d \t %s\n", p->id, p->name);
        // 判断next是否在有数据,为空指针的时候停止
        if (!p->next) break;
        p = p->next;
    }

    printf("\n");

    int input_a = 0;
    printf("请输入要查询的ID>>>\n");
    scanf("%d", &input_a);
    // 查找链表中ID为1的对象
    User* userp = find(&us[0], input_a);
    // 如果链表中查询到了值就打印
    if (userp) {
        printf("ID \t Name\n");
        printf("%d \t %s\n", userp->id, userp->name);
    }
    else {
        printf("未找到链表中ID为 %d 的数据, \n", input_a);
    }

    system("pause");
}

User* find(User* head, int id) {
    User* p = head;
    while (true)
    {
        if (p->id == id) {
            return p;
        }
        if (!p->next) break;
        p = p->next;
    }
    return NULL;
}

2、有头链表:用一个固定的头节点来指代整个链表,所有的对象挂载这个头节点下面,而头节点本身不包含有效数据

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

struct User
{
    int id;
    char name[20];
    User* next;
};

// 有头链表的定义:将一个对象作为节点,并把成员next初始化为NULL
// User head_user = { 1, "head", 0 }; // 0就是NULL
// 或者指定只定义next为空指针
User head_user = {0};

// 往头节点添加User对象(把对象附加到链表的开头)
void add(User* user);
// 往尾节点添加User对象(把对象附加到链表的末尾)
void insert(User* user);

/*
 有头链表:
    定义:用一个固定的头节点来指代整个链表,所有的对象挂载这个头节点下面,
        而头节点本身不包含有效数据
    构造:
 调试查看链表数据: 进入调试F5 => 调出监视窗口 => 搜索链表名称
*/
int main() {

    User user = {1, "张三", 0};
    insert(&user);
    User user2 = { 2, "李四", 0 };
    insert(&user2);

	return 0;
}

// 往头节点添加User对象(把对象附加到链表的开头)
void add(User* user) {
    // 传进来的对象追加到链表第一个
    user->next = head_user.next;
    head_user.next = user;
}

// 往尾节点添加User对象(把对象附加到链表的末尾)
void insert(User* user) {
    // 通过指针获取链表的内存地址
    User* p = &head_user;
    // 循环已存在的链表数据结构,目的得到链表的最后一个User的内存地址p
    while (p->next)
        p = p->next;
    // 将user赋给最后一个链表数据的next
    p->next = user;
    user->next = NULL;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cocosum

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值