C语言 有头结点的动态链表的创建

本文介绍了如何在C语言中高效地创建带有头结点的动态链表,避免不必要的内存浪费,并讲解了如何正确管理内存以防止内存泄漏。

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

条件:当输入0停止继续建立链表

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

typedef struct node {
	int data;						 //链表数据域
	struct node *next;		         //链表指针域
}Node;

void DeletNode(Node *pHead, int data);			//删除节点
void InsertListByHead(Node *pHead);             //头插法
void DestroyList(Node **pHead);					//销毁链表
Node * CreateList(); 							//创建空链表
void InsertListByTail(Node *pHead); 			//尾插法
void travelList(Node *pHead);					//遍历链表

int main() {
	Node *pHead;
	int data;
	
	pHead = CreateList();
//	InsertListByTail(pHead);
	InsertListByHead(pHead);
	travelList(pHead);

	printf("Please input the num you want to delete:");
	scanf("%d", &data);
	DeletNode(pHead, data);

	travelList(pHead);

	DestroyList(&pHead);
	travelList(pHead);				//验证链表是否销毁

	return 0;
}

void DeletNode(Node *pHead, int data) {
	Node *p ;

	while (pHead && pHead ->data != data) { //用头指针遍历
		p = pHead;  			  			//用p来保存要删除数据的前域
		pHead = pHead->next;
	}
	if (pHead == NULL) {
		printf("无此数据\n");
		return;
	}
	p->next = pHead->next;                 //让目标节点的前域指向目标节点的后域
	free(pHead);
}

void DestroyList(Node **pHead) {          //销毁链表,使用二重指针是害怕产生野指针,也可以使用一级指针
	Node *p;
	if ((*pHead)->next = NULL) return;    //如果是空表可以直接返回
	while ((*pHead)->next) {              //->的优先级高于*
		p = (*pHead)->next;
		free(*pHead);
		*pHead = p;					      //从头开始free
	}
}

void travelList(Node *pHead) {         
	pHead = pHead->next;
	while (pHead) {
		printf("%d\n", pHead->data);
		pHead = pHead->next;
	}
}

void InsertListHead(Node *pHead) {
	Node *cur;	
	int data;							
	
	scanf("%d", &data);
	while (data) {                          //此时的判断条件是输入0结束
		cur = (Node *)malloc(sizeof(Node));	//申请空间
		cur->data=data;
		cur->next = pHead->next;	        //新结点指向首结点
		pHead->next = cur;				    //新结点成为头结点

		scanf("%d", &data);
	}
}

void InsertListTail(Node *pHead) {
	Node  *cur, *tail;						    //一个是新节点,另一个记录尾结点的位置
	int data;

	scanf("%d", &data);
	while (pHead->next)  pHead = pHead->next;   //遍历找到尾结点
	tail = pHead;
	while (data) {
	    cur = (Node *)malloc(sizeof(Node));
	    cur->data = data;
		tail->next = cur;						//之前的尾结点指向新的节点
		tail = cur;								//新的节点成为尾结点
		
		scanf("%d", &data);
	}
	tail->next=NULL;							//当输入的数据不合法,退出循环,尾结点指向NULL
}

Node *CreatList(){
    Node *pHead = (Node *)malloc(sizeof(Node));
	pHead->next = NULL;    
	                 
	return pHead;
}

/*-------------------------------------------
void CreatList(Node **pHead) {					
	(*pHead) = (Node *)malloc(sizeof(Node));
	(*pHead)->next = NULL;                     
}
-------------------------------------------*/
/*--------------------------------------------
在创建头节点的时候,一级指针和二级指针无明显差别,
一级指针需要有返回值,即指向这个结构体类的指针类型
--------------------------------------------*/

以下片段是修改前,如果是先申请空间,然后直接将数据存放在里边,有些空间就浪费了,而且没有释放。

void InsertListTail(Node *pHead) {
	Node  *cur, *tail;						    //一个是新节点,另一个记录尾结点的位置
	cur = (Node *)malloc(sizeof(Node));

	scanf("%d", &cur->data);
	while (pHead->next)  pHead = pHead->next;   //遍历找到尾结点
	tail = pHead;
	while (cur->data) {
		tail->next = cur;						//之前的尾结点指向新的节点
		tail = cur;								//新的节点成为尾结点
		cur = (Node *)malloc(sizeof(Node));
		scanf("%d", &cur->data);
	}
	tail->next=NULL;							//当输入的数据不合法,退出循环,尾结点指向NULL
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值