//--------代码功能--------
// C语言
//反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
//说明 :
//1 ≤ m ≤ n ≤ 链表长度。
//示例:
//输入: 1->2->3->4->5->NULL, m = 2, n = 4
//输出 : 1->4->3->2->5->NULL
#include<stdio.h>
#include<malloc.h>
//可复制运行
//--------代码功能--------
// C语言
//反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
//说明 :
//1 ≤ m ≤ n ≤ 链表长度。
//示例:
//输入: 1->2->3->4->5->NULL, m = 2, n = 4
//输出 : 1->4->3->2->5->NULL
//单链表节点定义
typedef int DataType;
typedef struct Node {
DataType data;
struct Node* next;
}SLNode;
//初始化
void ListInitiate(SLNode** head) {
//申请头结点,由head指示其地址
*head = (SLNode*)malloc(sizeof(SLNode));
//置结束标记NULL
(*head)->next = NULL;
}
//求当前数据元素个数
//返回整型个数
int ListLength(SLNode* head) {
SLNode* p = head;
int size = 0;//指向头结点时为0;头结点不计入
while (p->next != NULL) {
p = p->next;
size++;
}
return size;
}
//在带头结点的单链表head的第i(0<=i<=size)个结点前插入一个存放数据元素x的结点
//插入成功返回1,失败返回0
int ListInsert(SLNode* head, int i, DataType x) {
SLNode* p, * q;
int j;
p = head;
j = -1;
while (p->next != NULL && j < i - 1) {
//最终让指针指向第i-1个结点
p = p->next;
j++;
}
if (j != i - 1) {
printf("插入元素位置参数错!");
return 0;
}
q = (SLNode*)malloc(sizeof(SLNode));//生成新结点
q->data = x;//新结点数据域赋值
q->next = p->next;//插入步骤1
p->next = q; //插入步骤2
return 1;
}
//获取第i个数据元素
int ListGet(SLNode* head, int i, DataType* x) {
SLNode* p;
int j;
p = head;
j = -1;
while (p->next != NULL && j < i) {
p = p->next;
j++;
}
if (j != i) {
printf("取元素位置参数错误!");
return 0;
}
*x = p->data;
return 1;
}
void Destroy(SLNode** head) {
SLNode* p, * p1;
p = *head;
while (p != NULL) {
p1 = p;
p = p->next;
free(p1);
}
*head = NULL;
}
//反转链表m,n区间的数据
//反转成功返回1,失败返回0
int LineInversion(SLNode* head, int m, int n) {
SLNode* cur = head;//指向第一个结点
SLNode* pre = NULL;//pre在cur的前面
SLNode* temp = NULL;//辅助
SLNode* front = NULL;//用于调整链表
SLNode* tail = NULL;//用于调整链表
int i = 1;
//若为空表,失败
if (head == NULL) {
printf("链表为空!操作失败!");
return 0;
}
//m不等于1时,调整p指向m
while (i<m&&m>1) {
pre=cur;
cur = cur->next;
i++;
}
front = pre;
tail = cur;
//反转链表
for (i = m; i <= n; i++) {
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
//调整链表
if (front != NULL) {
front->next = pre;
}
else {
head = pre;
}
tail->next = cur;
return 1;
}
//main函数实现 注:链表为带头结点单链表
main() {
//初始化链表
SLNode* head;
ListInitiate(&head);
//初始化链表数据域(带头结点)
int l=5, t = 0;
printf("请输入初始化链表长度:");
scanf("%d",&l);
printf("请输入初始化链表的%d个数据域:\n",l);
for (int i = 0; i < l; i++) {
scanf("%d", &t);
ListInsert(head, i, t);
}
//反转
int m = 1, n = l;
printf("请输入反转区间(m,n):");
scanf("%d%d", &m, &n);
int ifSuccee = 0;
LineInversion(head, m+1, n+1);//反转,该链表为带头结点链表,需加 1
if (ifSuccee == 1)
printf("反转成功!\n");
//输出反转后的链表
int x;
for (int i = 0; i < ListLength(head); i++) {
ListGet(head, i, &x);
printf("%d ", x);
}
//清空链表释放内存
Destroy(&head);
}