一种好玩的链表遍历方法

一种链表遍历方法(printLots)

printLots遍历简介:
给定两个链表,list = [1, 2, 3, 4, 5, 6],slots = [1, 2, 4],list与slots中的元素都是升序,可以不严格升序,也就是元素可以存在相等的情况。
其中list是待遍历的链表,slots中的元素表示的是一组位置元素,我们需要实现一种打印方式,打印list中指定位置的元素,而这些位置由slots指定,比如本例中,slots链表中的元素1,表示要输出list中位置1处的元素,也就是2,依此类推。

c语言简单实现:

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

// 链表节点类型
struct listNode {
	// 链表节点的数据域
	int data;
	// 链表节点的指针域
	struct listNode *next;
};

// 尾插法创建单链表,带头结点
struct listNode *createList(int *arr, int len) {
	struct listNode *head = (struct listNode *) malloc(sizeof(struct listNode));
	if (!head) {
		exit(EXIT_FAILURE);
	}
	head->next = NULL;

	struct listNode *tail = head;
	for (int i = 0; i < len; i++) {
		struct listNode *node = (struct listNode *) malloc(sizeof(struct listNode));
		if (!node) {
			exit(EXIT_FAILURE);
		}
		node->data = arr[i];
		node->next = NULL;
		tail->next = node;
		tail = node;
	}
	return head;
}

// 释放单链表的内存空间
void freeList(struct listNode *head) {
	struct listNode *next = NULL;

	while (head) {
		next = head->next;
		free(head);
		head = next;
	}
}

// 实现printLots打印
struct listNode *printLots(struct listNode *list, struct listNode *lots) {
	// 用来遍历list的游标指针
	struct listNode *listCur = list->next;
	// 用来遍历lots的游标指针
	struct listNode *lotsCur = lots->next;
	
	// 存放lots打印结果
	struct listNode *resHead = (struct listNode *) malloc(sizeof(struct listNode));
	struct listNode *resTail = resHead;
	if (!resHead) {
		exit(EXIT_FAILURE);
	}
	resHead->next = NULL;

	// 当前遍历的list中的元素的位置
	int pos = 0;
	while (listCur && lotsCur) {
		// 只有pos指向的位置和lots链表中对应位置的值相等时
		// 才将list中的元素进行记录,这里采用的是拷贝的形式
		// 为的是不破坏原有链表list
		if (pos == lotsCur->data) {
			struct listNode *node = (struct listNode *) malloc(sizeof(struct listNode));
			if (!node) {
				exit(EXIT_FAILURE);
			}
			// 将node插入到res中
			node->next = NULL;
			node->data = listCur->data;
			resTail->next = node;
			resTail = node;
			// 一旦lots链表中的某个节点被访问过了,那么
			// 该节点就不允许被再次访问
			lotsCur = lotsCur->next;
		} else if (pos > lotsCur->data) {
			// 如果pos大于lotsCur,只有一种情况
			// 就是用户给出的lots链表中的元素有复数
			lotsCur = lotsCur->next;
		} else {
			// 如果pos的值小于lots中当前节点中记录的位置的值
			// 说明还需要继续移动pos往后走
			listCur = listCur->next;
			pos++;
		}
	}	
	// 返回结果集
	return resHead;
}

// 打印链表的函数
void printList(struct listNode *head) {
	printf("print:\n");

	int i = 0;
	head = head->next;
	while (head) {
		printf("i: %d\t%d\n", i++, head->data);
		head = head->next;
	}
}

int main(void) {
	int dataArr[] = {1, 2, 3, 4, 5, 6};
	int lotsArr[] = {-1, -2, 1, 1, 1, 2, 4, 4, 4, 5, 5, 8, 8};
	
	struct listNode *list = createList(dataArr, 6);
	printList(list);	

	struct listNode *lots = createList(lotsArr, 13);
	printList(lots);

	struct listNode *res = printLots(list, lots);
	printList(res);

	freeList(list);
	freeList(lots);
	freeList(res);

	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值