单循环链表是C语言中比较常见的一种链式储存结构。 相较于普通的单链表,其特点就在于单循环链表的尾指针指向的是头结点。 即: 1.单链表 2. 单循环链表的有点就在于方便访问第一个结点,还方便访问最后一个结点。 那么,话不多说,先建立一个单循环链表: (先给出相关的定义:PNode 、LinkList 分别表示结点和链表,DataType即int,结构体Node含有两个成员:data和next指针)
typedef int DataType; typedef struct Node* PNode; typedef struct Node* LinkList; struct Node { DataType data; struct Node* next; };接下来就是建立单循环链表的函数: ps:这样建立的单链表,会有一个空的头节点(head)。
LinkList CreateList_Tail_loop() { LinkList head = (LinkList)malloc(sizeof(struct Node)); PNode cur = NULL; PNode tail = head; DataType data; printf("please input some Numbers:\n"); scanf_s("%d", &data); while (data != -1) { cur = (struct Node*)malloc(sizeof(struct Node)); cur->data = data; tail->next = cur; tail = cur; scanf_s("%d", &data); } tail->next = head;//尾指针指向头结点 return tail; }链表建立好了之后,就可以开始进行移动了~
ps: tail为已经建立好的链表 temp用来记录头结点 pre为p的前驱结点,p为用于判断的结点。
PNode Move_Odd_Even(LinkList tail) { PNode last = NULL, p = NULL, pre = NULL, temp = NULL; int flag = 1; last = tail; temp = tail->next; pre = tail->next; p = (tail->next)->next; tail->next = NULL; while (flag) { if (p == tail) { break; } if ((p->data) % 2 == 0) { pre->next = p->next; p->next = NULL; last->next = p; last = p; p = pre->next; } else { pre = p; //记录p的前驱 p = p->next; } } if (tail->data % 2 == 0) { pre->next = p->next; p->next = NULL; last->next = p; last = p; } last->next = temp; tail = last; return tail; }来看全部代码与运行结果:
//实现对单循环链表中奇数和偶数结点的移动 #include<stdio.h> #include<stdlib.h> #include <cstddef> typedef int DataType; typedef struct Node* PNode; typedef struct Node* LinkList; struct Node { DataType data; struct Node* next; }; PNode Move_Odd_Even(LinkList tail); LinkList CreateList_Tail_loop() { LinkList head = (LinkList)malloc(sizeof(struct Node)); PNode cur = NULL; PNode tail = head; DataType data; printf("please input some nums:\n"); scanf_s("%d", &data); while (data != -1) { cur = (struct Node*)malloc(sizeof(struct Node)); cur->data = data; tail->next = cur; tail = cur; scanf_s("%d", &data); } tail->next = head; return tail; } void print(LinkList tail) { PNode head = tail->next; PNode p = head->next; while (p != head) { printf("%d ", p->data); p = p->next; } } void DestoryList_Link(LinkList tail) { PNode pre = tail->next; PNode p = pre->next; while (p != tail) { free(pre); pre = p; p = pre->next; } free(pre); free(tail); } int main() { LinkList tail = NULL; LinkList p = NULL; tail = CreateList_Tail_loop(); p = Move_Odd_Even(tail); print(p); DestoryList_Link(tail); return 0; } PNode Move_Odd_Even(LinkList tail) { PNode last = NULL, p = NULL, pre = NULL, temp = NULL; int flag = 1; last = tail; temp = tail->next; pre = tail->next; p = (tail->next)->next; tail->next = NULL; //第一个结点的data为奇数时 while (flag) { if (p == tail) { break; } if ((p->data) % 2 == 0) { pre->next = p->next; p->next = NULL; last->next = p; last = p; p = pre->next; } else { pre = p; //记录p的前驱 p = p->next; } } if (tail->data % 2 == 0) { pre->next = p->next; p->next = NULL; last->next = p; last = p; } last->next = temp; tail = last; return tail; }运行结果: 刚写的单循环链表时候还是遇到了蛮多的坑,吃了一些 有无空头节点 的苦。若是题目要求写一个函数实现链表操作的某一个功能时,一定要注意题中提供的链表有无头结点!
可以将tail以及其后面几个结点的值打印出来,这样就可以知道链表的模样了。 第一次写博客,若是有哪些写错的地方,欢迎大家在评论区留言指正~