头插法和尾插法创建链表(有无头结点)

头插法和尾插法创建链表(有无头结点)

1 头插法

1.1头插法建表规则:

  1. 从一个空表开始,读取字符数组a中的字符,生成新节点,将读取的数据存放到新节点的数据域中,然后将新节点插入到当前链表的表头上,直到读完字符数组a的所有元素为止。
  2. 头插法建表简单,但生成的链表中节点的次序和原数组的次序相反,若希望两者的次序一致,可采用尾插法建立

1.2 头插法建表代码实现

/*
	节点的结构声明
*/
typedef int ElementType;

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

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

	+------+	     +------+	 +------+	 +------+
	| 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;
}

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

	 		  +------+	  +------+	   +------+	   +------+
			  | 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;
}

2 尾插法

2.1 尾插法建表规则:

该算法是将新节点插到当前链表的表尾上,为此必须增加一个尾指针rear,使其始终指向当前链表的尾节点

2.2 尾插法建表代码实现:

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

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

*/  思想:新增一个尾指针rear,将新结点插入到表尾,尾指针始终指向head便于建表
List TailCreate(void)
{
	ElementType x; // 保存 Node 中的 data 数据
	List p;
	List head; // 头结点
	List rear; // 因为尾插法需要在尾部插入,所以要有个指针来保存尾的位置
	head = (List)malloc(sizeof(struct Node));
	head->Next = NULL;
	head = rear; // 链表为空,头和尾指向同一个位置
	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;
}

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

	+------+	+------+	+------+
	|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;
}
  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值