C语言-链表的创建头插法和尾插法(有无头节点)

链表构建详解
本文详细介绍了使用头插法和尾插法构建链表的过程,并分别探讨了有头节点和无头节点的情况。通过具体的代码实现,帮助读者理解不同场景下链表构建的特点。

结构声明

typedef int ElementType;

typedef struct Node {
	ElementType data;
	struct Node *Next;
} *List;

1 头插法(有头节点)

/* 
	建立链表 - 头插法 - 有头节点 

	+------+	     +------+	 +------+	 +------+
	| head |   =>    |node_1| -> |node_2| -> |node_3| -> NULL
	+------+	     +------+	 +------+	 +------+
	      \			  /
		     +------+
		     |   p  |
		     +------+

*/
List HeadCreate(void)
{
	ElementType x; // 保存 Node 中的 data 数据
	List p; // 临时指针,用于保存声明的节点
	List head; // 整个链表的头结点;
	head = (List)malloc(sizeof(struct Node));
	head->Next = NULL;
	head->data = 0; // 头节点的 data 域用于保存链表的长度
	scanf("%d", &x);

	while (x != -1) { // 当 x 等于 -1 的时候,停止创建链表
		p = (List)malloc(sizeof(struct Node));
		p->data = x;
		p->Next = head->Next;
		head->Next = p;
		head->data++; // 链表的长度加 1
		
		scanf("%d", &x); // 读取下一个节点的数据
	}
	return head;
}

2 头插法(无头节点)

/*
	建立链表 - 头插法 - 没有头节点

	 		  +------+	  +------+	   +------+	   +------+
			  | head | -> |node_1| ->  |node_2| -> |node_3| -> NULL
	   ^  	  +------+	  +------+	   +------+	   +------+
       |
	+------+
	|  p   |
	+------+

*/
List HeadCreate(void)
{
	ElementType x; // 保存 Node 中的 data 数据
	List p;
	List head;
	head = NULL;
	scanf("%d", &x);

	while (x != -1) {
		p = (List)malloc(sizeof(struct Node));
		p->data = x;
		if (head == NULL) {	// 若第一次创建节点,则将该点设置为头节点
			head = p;
			p->Next = NULL;
		} else { // 若不是第一次创建节点,则直接将新节点接到链表头
			p->Next = head;
			head = p;
		}
		scanf("%d", &x);
	}
	return head;
}

3 尾插法(有头节点)

/* 
	创建链表 - 尾插法 - 有头节点

	+------+	+------+	+------+
	| head | -> |node_1| -> |node_2|   ____
	+------+	+------+	+------+	  |
										  v
						+------+ 	  +------+
						| rear |  ->  |   p  |
						+------+	  +------+

*/
List TailCreate(void)
{
	ElementType x; // 保存 Node 中的 data 数据
	List p;
	List head; // 头结点
	List rear; // 因为尾插法需要在尾部插入,所以要有个指针来保存尾的位置
	head = (List)malloc(sizeof(struct Node));
	head->Next = NULL;
	rear = head; // 链表为空,头和尾指向同一个位置
	scanf("%d", &x);

	while (x != -1) {
		p = (List)malloc(sizeof(struct Node));
		p->data = x;
		rear->Next = p;
		rear = p;
	}
	rear->Next = NULL; // 链表建立结束后将最后一个节点指向 NULL
	return head;
}

4 尾插法(无头节点)

/* 
	创建链表 - 尾插法 - 没有头节点 

	+------+	+------+	+------+
	|node_1| -> |node_2| -> |node_3| 	____
	+------+	+------+	+------+	   |
										   v
							+------+	+------+
							| rear | ->	|   p  |
							+------+	+------+

*/
List TailCreate(void)
{
	ElementType  x;
	List p;
	List head;
	List rear;
	head = NULL;
	rear = NULL;
	scanf(%d, &x);

	while (x != -1) {
		p = (List)malloc(sizeof(struct Node));
		p->data = x;
		if (head == NULL) { // 创建链表的第一个节点
			head = p;
			rear = p;
			p->Next = NULL;
		} else {
			rear->Next = p;
			rear = p;
		}
		scanf("%d", &x);
	}
	rear->Next = NULL; // 链表建立结束后将最后一个节点指向 NULL(尾插法中不要遗漏)
	return head;
}
头节点链表是一种简单的数据结构,以下从原理、实现及应用方面进行介绍。 ### 原理 无头节点链表链表起始位置直接是存储数据的节点,无专门不存有效数据的头节点。每个节点包含数据域指向下一节点的指针域,通过指针连接各个节点形成链式结构,可实现数据的动态存储与灵活访问 [^1]。 ### 实现 - **C语言实现**:在C语言里,借助指针操作达成无头节点链表创建入、删除、查找等基本操作。创建链表节点,需动态分配内存以存储节点数据与指针;入节点时,要调整指针指向,确保新节点正确接入链表;删除节点时,释放节点内存并调整指针;查找节点则是遍历链表,比对节点数据;遍历释放链表内存时,依次访问节点并释放所占内存 [^2]。 - **Python实现**:以Python创建头节点链表,可定义节点类链表类。节点类含数据属性指向下一节点的引用,链表类包含创建入、删除等操作方法 [^1]。 ### 应用 - **节省空间与提高效率**:无头节点链表结构简洁,在需节省空间提高操作效率的场景更受欢迎。在低级语言如C语言实现中,其能减少内存使用,因无需为链表额外分配不存储有效数据的头节点。在需频繁入或删除操作的场景,可提供更快操作速度,减少对头节点的特殊处理 [^1]。 - **作为子结构**:无单向非循环链表结构简单,通常不单独用于存储数据,更多作为其他数据结构的子结构,如哈希桶、图的邻接表等 [^4]。 ### 代码示例(Python创建头节点链表) ```python # 定义节点类 class Node: def __init__(self, data): self.data = data self.next = None # 定义链表类 class LinkedList: def __init__(self): self.head = None # 入节点 def insert(self, data): new_node = Node(data) if not self.head: self.head = new_node else: current = self.head while current.next: current = current.next current.next = new_node # 遍历链表 def traverse(self): current = self.head while current: print(current.data, end=" -> ") current = current.next print("None") # 创建链表实例 linked_list = LinkedList() # 入节点 linked_list.insert(1) linked_list.insert(2) linked_list.insert(3) # 遍历链表 linked_list.traverse() ```
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值