创建单链表、malloc函数、单链表反转实例(1-2-3-4-5)

本文详细介绍了链表的基本概念,包括链表的结构定义、节点的构成以及链表的初始化过程。通过C语言示例代码,展示了如何创建链表、实现链表的反转以及节点的删除与插入操作。此外,还分析了链表反转算法的时间复杂度。

链表实现
在这里插入图片描述
链表每一个节点包含数据域和指针域,第一个节点数据域为NULL,指针域指向下一个节点数据域。

//定义一个链表结构
//用typedef为struct数据类型取名为list
//Node是定义结构体时的标签,与struct是一个整体
typedef struct Node   
{
      int date;   //链表一个节点的数据域
      struct Node *next;   //定义一个指向结构体类型的指针
  }list;     //同时也表示结构体变量

typedef struct Node *a;//定义结构体指针变量
list *a;

访问节点数据域:p->data
节点指针域指针:p->next,指向下一个节点


//初始化一个链表
list *create(int n)
{  
       list *head,*node,*end;   //定义头节点、普通节点、尾节点,每个节点都是一个结构体类型
       head = (list*)malloc(sizeof(list));//malloc是动态内存分配函数,如果分配成功则返回指向被分配内存的结构体类型指针
       end=head;    //若是空链表,则头尾节点一样(空链表),给end一个初始化指向,形成空链表
       for(int i = 0;i < n; i++){
         node = (list*)malloc(sizeof(list));   //分配内存
         scanf("%d",&node->data);
         end->next = node;//下一个地址就是node地址(end->next 表示指向下一个地址)
         end = node;//end指针指向node里面的内容(数据域与指针域),清空node
         //end在前面还没有给他分配地址空间,让end指向node地址,node再次去获取。
}
  end->next = NULL;   //结束创建
  return head;    
}

关于malloc函数的用法

C语言中,malloc是动态内存分配函数。
函数原型:void malloc(unsigned int num_bytes);
参数:num_bytes 是无符号整型,用于表示分配的字节数。
返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。void
表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者…)
功能:分配长度为num_bytes字节的内存块
注意:当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。关于该函数的原型,在以前malloc返回的是char型指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进行类型转换。

  1. 问题描述
    已知1个List: 1->2->3->4->5;

要求把List反转变为:5->4->3->2->1。

  1. 问题分析
    问题很简单,新创建一个list:
    (1)从List中取首元素l;
    (2)把这个元素l,按照前插法插入到list中
    (3)重复(1)(2),直到List中没有元素
  2. 算法实现
//方法三从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。

typedef struct list{
   int data;
   struct list* next;
}List;

List* ReverseList(List *list)   //定义一个结构体类型的指针函数,返回一个指针
{
	if( list == NULL )          //如果指针指向空值,返回(链表为空)
		return;
		
	List* new_list = NULL;     //定义一个新的空链表(新的结构体指针指向空)
	List* next_node;     //定义一个指针指向链表下一个节点
	while( list != NULL )     //如果不是空链表,执行
	{
		next_node = list->next;       //用指针指向链表下一个节点,
		list->next = new_list;       //该节点指向新的链表地址
		
		new_list = list;      //新链表指针指向链表
		
		list = next_node;    //链表指向下一个节点
	}//while
	
	return new_list;   返回新的链表
}

算法需要注意的地方就是关于指针的操作,其中在对list操作时,一定要把list->next保存起来。
4. 算法分析
算法的复杂度为O(n)。

方法二:使用三个指针遍历单链表,逐个链接点进行反转。

typedef struct List
{
     int data;
     struct List* next
}list;

list * reverselist(list * head)
{
 if(head==NULL||NULL==head->next) 
         return head;
  list * p,*q,*r;
  p=head;  // p指向head
  q=head->next;   //q指向head->next
  head->next=NULL;   //head->next指向NULL
}

while(q){
r=q->next;   //r指向q->next
q->next=p;   //q->next指向p
p=q;  //p指向q
q=r;//q指向r
}

head=p;//head指向p
return head;

在这里插入图片描述
在这里插入图片描述

//删除链表节点
s=p->next;
p->next=s->next;
free(s);


//插入链表节点
s->data=x;    //给节点装值
s->next=p->next;
p->next=s;

<think>好的,我现在需要帮助用户解决如何在C语言中使用malloc函数创建单链表节点的问题。首先,我得回忆一下单链表的基本结构。根据用户提供的引用内容,单链表的每个节点由数据域和指针域组成,指针指向下一个节点。用户提到他们想了解如何使用malloc来分配内存,所以我的回答需要重点放在malloc的使用上。 首先,我应该先明确单链表节点的结构。在C语言中,通常使用结构体来定义节点,结构体包含数据和指向下一个节点的指针。比如: ```c typedef int SLTDataType; typedef struct SListNode { SLTDataType data; struct SListNode* next; } SLTNode; ``` 这里用户引用的代码中使用了SLTNode结构体,所以可能需要用类似的定义。接下来,创建节点的函数需要使用malloc来动态分配内存。根据引用中的示例函数BuySLTNode,我需要详细解释这个函数的作用。 然后,我需要分步骤说明如何创建节点。第一步是使用malloc申请内存,这里需要计算结构体的大小。用户提供的代码中使用了sizeof(SLTNode),这应该正确。第二步是检查malloc是否成功,如果返回NULL,说明内存分配失败,这时候需要处理错误,比如使用perror并退出程序,如引用中的例子所示。第三步是给新节点的数据域赋值,并将指针域初始化为NULL。最后返回新节点的指针。 另外,需要注意内存泄漏的问题,确保每次分配的内存最终都会被释放。但用户的问题主要集中在创建节点上,所以可能不需要深入讨论释放的部分,不过可以简要提及。 可能用户还会有疑问,比如为什么要用动态内存分配,或者如何处理分配失败的情况。这时候可以引用提供的参考资料,比如引用[1]中的代码示例,说明在申请内存失败时如何处理错误。同时,引用[2]和[3]解释了单链表的结构,可以辅助说明节点各个部分的作用。 最后,生成相关问题时要围绕malloc的使用、错误处理、节点初始化以及单链表的操作展开。比如如何释放节点内存,头插法的实现,或者处理分配失败的替代方法等。 总结一下,回答的结构应该是先介绍节点结构体的定义,然后分步骤讲解malloc的使用,错误检查,数据赋值,最后给出完整的代码示例。同时,结合用户提供的引用内容,确保回答的准确性,并在末尾添加相关问题帮助用户进一步学习。</think>### 如何使用`malloc`函数创建单链表节点 #### 1. 单链表节点的结构定义 单链表节点由**数据域**和**指针域**组成,需用结构体实现: ```c typedef int SLTDataType; // 假设数据类型为整型 typedef struct SListNode { SLTDataType data; // 数据域 struct SListNode* next; // 指针域(指向下一个节点) } SLTNode; ``` #### 2. 使用`malloc`分配内存的步骤 **(1) 申请内存空间** ```c SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode)); ``` - `sizeof(SLTNode)`计算节点结构体所需内存大小[^4] - `malloc`返回`void*`类型指针,需强制转换为`SLTNode*` **(2) 检查内存分配是否成功** ```c if (newnode == NULL) { perror("malloc fail"); exit(-1); // 终止程序并返回错误码 } ``` - 内存不足时`malloc`返回`NULL`,必须检查以避免后续操作崩溃[^1] **(3) 初始化节点成员** ```c newnode->data = x; // 设置数据域的值 newnode->next = NULL; // 新节点默认不指向其他节点 ``` #### 3. 完整函数实现 ```c // 创建新节点函数 SLTNode* BuySLTNode(SLTDataType x) { SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode)); if (newnode == NULL) { perror("malloc fail"); exit(-1); } newnode->data = x; newnode->next = NULL; return newnode; } ``` #### 4. 使用示例 ```c int main() { SLTNode* node1 = BuySLTNode(10); // 创建数据为10的节点 SLTNode* node2 = BuySLTNode(20); // 创建数据为20的节点 node1->next = node2; // 链接两个节点 // ...后续链表操作 return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值