王道数据结构实践代码----单链表的实现(C语言版)

本文是根据王道2021年数据结构考研复习指导,用C语言实现单链表的实践代码,涵盖链表初始化、插入、删除、查询等操作。文中探讨了C语言中指针与C++引用的转换问题,以及头插法与尾插法的区别,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

王道数据结构实践代码----单链表的实现(C语言版)

前言

日期:2021年8月26日
书籍:王道2021年数据结构考研复习指导
代码内容:实现单链表的实现,包括初始化,插入新元素,删除新元素,输出,查询

代码难点

1.C语言的指针和C++的引用转换


指针我太阳你个**
简而言之,王道书上的单链表声明和初始化是以C++为模板的,C语言无法直接使用,需要做一定的转换,介于我指针学的也不是很好,就不说这中间的转换过程和原理了,日后有闲暇了再慢慢研究

2.头插法和尾插法的区别,带头指针和不带头指针的区别

引入头结点后,可以带来两个优点:
①由于第一个数据结点的位置被存放在头结点的指针域中,因此在链表的第一个位置上的操作和在表的其他位置上的操作一致,无须进行特殊处理。
②无论链表是否为空,其头指针都指向头结点的非空指针(空表中头结点的指针域为空)因此空表和非空表的处理也就得到了统一。
所以,没事儿写代码就把头指针带着吧

头插法vs尾插法
采用头插法建立单链表时,读入数据的顺序与生成的链表中的元素的顺序是相反的。
头插法建立单链表的算法虽然简单,但生成的链表中结点的次序和输入数据的顺序不一致。若希望两者次序一致,则可采用尾插法。该方法将新结点插入到当前链表的表尾,为此必须增加个尾指针r,使其始终指向当前链表的尾结点.

各功能代码

C语言自定义bool操作

//C语言自定义bool操作
#define bool char
#define false 0
#define true 1

单链表结构体定义

/*数据元素类型*/
typedef int ElemType;

/*单链表结构体定义*/
typedef struct LNode        //定义单链表结点类型
{
   
   
    ElemType data;          //每个结点存放一个数据元素
    struct LNode *next;     //指针指向下一节点
}LNode,*LinkList;

/*
    上面的代码等价于
    typedef struct Lnode Lnode;
    typedef struct Lnode * Linklist;
*/

//LinkList L; //声明一个指向单链表第一个结点的指针,这种方法代码可读性更强
/*
    上面的代码也可写成:
    LNode *L;
    //声明一个指向单链表第一个结点的指针,但这种方法可读性不强,
    //无法第一时间看出L是指向整个链表的头指针,还是仅仅是个新的结点
*/

链表初始化函数

LinkList ListInit()
{
   
   
    //[1]申请一块LinkList类型的存储空间给L
    LinkList L = (LinkList)malloc(sizeof(LinkList));
    //[2]设置L的指针域为空
    L->next = NULL;
    //返回L指针
    return L;
}

创建新结点函数

//创建新结点
LNode* createNote(int data)
{
   
   
    //[1]为新节点申请空间
    LNode* newNode = (LNode*)malloc(sizeof(LNode));
    //[2]如果内存满了,则分配失败,返回0
    if(newNode == NULL) 
    {
   
   
        printf("分配结点失败,请检查内存!");
        return NULL;
    }
    //[3]为新节点的数据域和指针域分别赋值
    newNode->data = data;
    newNode->next = NULL;
    //[4]返回新节点的指针
    return newNode;
}

头插法&尾插法

//头插法
bool ListHeadInsert(LinkList L,ElemType data)
{
   
   
    //[1]调用创建新节点函数,为其赋值
    LNode* newNode = createNote(data);
    //[2]先给新节点的指针域赋值(指向原来链表的第一个节点)
    newNode->next = L->next;
    //[3]再让头结点指向新结点
    L->next = newNode;
    //[4]返回true,表示插入成功
    return true;
}

//尾插法(不带尾指针的尾插法,因此每次插入新元素都需要遍历列表,所以时间复杂度为O(n))
bool ListTailInsert(LinkList L,ElemType data)
{
   
   
    //[1]申请新节点
    LNode* newNode = createNote(data);
    //[2]生成工具指针
    LNode* p = L->next;
    //[3]遍历链表,找到最后的元素,用工具指针指向它
    while (p->next != NULL)
    {
   
   
        p = p->next;
    }
    //[4]尾插入新节点
    newNode->next = NULL;
    p->next = newNode;
}

查询

//按序号查找节点值
LNode *GetElem(LinkList L,int i)
{
   
   
    //[1]设置一个变量计数
    int j = 1;
    //[2]设置待返回的结点p,开始指向第一个结点
    LNode *p = L->next;
    //[3]检查参数
    if(i == 0) {
   
   p = L; 
### C语言链表实现与应用 对于C语言中的链表,理解其基本概念和操作至关重要。链表是一种线性数据结构,其中的数据元素通过指针链接起来[^1]。 #### 单链表定义 单链表由一系列节点组成,每个节点包含两部分:存储数据的部分以及指向下一个节点地址的指针。最后一个节点的指针为空(NULL),表示链表结束。为了创建这样的列表,通常会定义一个带有两个成员变量的`struct`——一个是用于保存实际数据项的数据域;另一个是指向同一类型的下一项的指针域。 ```c typedef struct Node { int data; struct Node* next; } LinkList; ``` 此代码片段展示了如何声明一个简单的整数型单向链表节点类型。 #### 基本操作函数 针对上述提到的操作需求,在这里提供几个常用的方法来处理单链表- **初始化头结点** 创建一个新的空链表只需要分配内存给头部并将其`next`字段设置为NULL即可。 ```c LinkList* initLinkList() { LinkList *head = (LinkList*)malloc(sizeof(LinkList)); head->next = NULL; return head; } ``` - **插入新节点** 插入可以发生在任意位置,但最常见的是在链表开头或者结尾处添加新的元素。下面的例子是在指定索引之前加入新值。 ```c bool insertBeforeIndex(LinkList* head, unsigned index, int value){ if (!head || !index) return false; LinkList* newNode = (LinkList *) malloc(sizeof(LinkList)); newNode->data = value; LinkList* current = head; for(unsigned i=0;current && i<index-1;i++){ current=current->next; } if(!current) return false; newNode->next = current->next; current->next=newNode; return true; } ``` - **删除特定节点** 删除某个具体数值对应的第一个匹配项可以通过遍历整个序列直到找到目标为止,之后调整前后相邻两项之间的连接关系完成移除动作。 ```c bool deleteByValue(LinkList* head,int target){ if(head==NULL)return false; LinkList* prev=NULL,*curr=head->next; while(curr&&curr->data!=target){ prev=curr; curr=curr->next; } if(curr==NULL)return false;//not found free(curr); prev?prev->next=curr->next:head->next=curr->next; return true; } ``` - **打印链表内容** 输出当前存在的所有记录以便于调试查看或展示最终结果。 ```c void output(LinkList *head) { LinkList *p; p = head->next; printf("H"); while (p != NULL) { printf("-->%d", p->data); p = p->next; } printf("\n"); } ``` 以上就是一些有关C语言单链表的基础知识点介绍及其典型应用场景下的编程实践案例[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值