一种链表遍历方法(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;
}