链表一趟扫描反转全代码实现(C语言)——数据结构

//--------代码功能--------
// 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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值