C语言单链表的建立和输出(详细分析)

1、头文件

#include<stdio.h>
#include<stdlib.h>//包含了malloc函数,可以用malloc.h代替

C语言中malloc是动态内存分配函数

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

2、节点的构成

struct Link {
	int data;
	struct Link* next;
};

为了书写更加简洁方便,我们可以使用tepyof关键词:

typeof struct Link {
	int data;
	struct Link* next;
}* Linknode;

3、单链表的创建

(1)无头节点的创建

struct Link* CreatLink(struct Link* head) {
	struct Link *p=NULL, *q=NULL;
	int data;
	scanf("%d",&data);
	while(data != -1) {
		p = (struct Link*)malloc(sizeof(struct Link));
		p->data = data;
		if (head == NULL)//这里判断的含义是指如果这个单链表里一个数都没有,那么就让head节点成为它第一个节点。 
			head = p;
		else
			q->next = p;
		q = p;
		scanf("%d",&data);
	}
	p->next = NULL;
	return head;
}

(2) 有头节点的创建

 struct Link* CreatLink(struct Link* head) {
	struct Link *p=NULL, *q=NULL;
	int data;
    p = (struct Link*)malloc(sizeof(struct Link));
    head = p;
    q = p;
	scanf("%d",&data);
	while(data != -1) {
		p = (struct Link*)malloc(sizeof(struct Link));
		p->data = data;
		q->next = p;
		q = p;
		scanf("%d",&data);
	}
	p->next = NULL;
	return head;
}

头节点定义:

头节点是为了操作的统一、方便而设立的,一般来说,头节点放在第一元素节点之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等)。有头节点后,对在第一元素节点前插入节点和删除第一节点,其操作与对其他节点的操作统一了。而且无论链表是否为空,头指针均不为空。
  首元节点是第一元素节点,它是头节点后边的第一个节点。

区别

  • 有头节点的浪费空间,但易理解,边界好处理,不易出错,代码简单;
  • 无头节省空间,难理解,边界不易处理,代码稍复杂;

4、单链表的输出

(1)无头节点的输出

void PrintLink(struct Link *head) {
	struct Link *h = head;
	if (h == NULL) {//判空
		printf("The Link is null");
		return;
	}
	while (h != NULL) {
		printf("%d ", h->data);
		h = h->next;
	}
}

(2)有头节点的输出

void PrintLink(struct Link *head) {
	struct Link *h = head->next;//跳过头节点
	if (h == NULL) {//判空
		printf("The Link is null");
		return;
	}
	while (h != NULL) {
		printf("%d ", h->data);
		h = h->next;
	}
}

5、完整代码演示

无头节点代码:

#include<stdio.h>
#include<stdlib.h>
struct Link {
	int data;
	struct Link* next;
};
struct Link* CreatLink(struct Link* head) {
	struct Link *p=NULL, *q=NULL;
	int data;
	scanf("%d",&data);
	while(data != -1) {
		p = (struct Link*)malloc(sizeof(struct Link));
		p->data = data;
		if (head == NULL)
			head = p;
		else
			q->next = p;
		q = p;
		scanf("%d",&data);
	}
	p->next = NULL;
	return head;
}
void PrintLink(struct Link *head) {
	struct Link *h = head;
	if (h == NULL) {
		printf("The Link is null");
		return;
	}
	while (h != NULL) {
		printf("%d ", h->data);
		h = h->next;
	}
}
int main(void) {
	struct Link *head=NULL;
	head = CreatLink(head);
	PrintLink(head);
    free(head);//释放malloc创建的空间
    
	return 0;
}

输入:

1 2 3 4 5 6 -1

输出:

1 2 3 4 5 6 

注:如果有任何问题欢迎大家和我一起讨论

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐