【数据结构】设一个带头结点的单链表L,大部分元素为正数,少数为负数,编写函数,采用高效的算法调整链表,实现将负数结点移到链表尾部,并返回调整后链表中第一个负数结点的位置。

该文介绍了一种使用尾插法对链表中的节点按正负数进行分组排序的方法。首先定义工作指针tail和minus,遍历链表,正数节点添加到tail后面,负数节点添加到minus前面。最后返回minus作为负数序列的头结点,实现链表的正负数分组。
摘要由CSDN通过智能技术生成

1. 算法思路

使用尾插法实现该要求。实现按步骤为:

  • 定义工作指针tail和minus,分别指向正数的最后一个结点以及负数的头结点。
  • 循环遍历链表,将结点使用尾插法插入正结点的末尾。
  • 如果插入的是正结点,则移动tail;如果是负结点,则移动minus。

2.定义结构体

typedef struct LNode {
    int data;
    struct LNode *next;
} LNode, *LinkList;

3.函数实现

定义工作指针:

  • p: 用于遍历单链表
  • tail: 指向正数结点的尾部
  • minus: 指向负数结点的头部,初始值为NULL
  • s: 用于暂时指向当前p结点

循环遍历A链表,使用p指针指向当前结点,判断当前的正负:

  • p->data >= 0: 当前结点为正数,将其插入到正数的最后面,然后修改tail指针指向该结点,此时tail仍指向正数的尾结点,minus指向负数的头结点;
  • p->data < 0: 当前结点为负数,将其插入到正数的最后面,即负数的最前面,然后移动minus指针到当前指针,此时tail仍指向正数的尾结点,minus指向负数的头结点。
  • 重复上述步骤直到遍历完成。此时返回负数的头结点minus,然后可遍历输出查看负数结点。
LNode* SortList(LinkList A) {
    LNode *p, *tail = A, *minus = NULL,*s = NULL;
    if(!A) {
        return NULL;
    }
    p = A->next;
    while(p) {
        tail->next = p;
        s = p;
        p = p->next;
        s->next = minus;
        if(s->data >= 0) {//非负数,移动tail指针
            tail = s;
        } else {//负数
            minus = s;
        }
    }
    return minus;
}

4.测试结果

LinkList A = (LinkList)malloc(sizeof(LNode));
int a[] = {1, 2, -4, 3, 4, -1, 7, -3};

在这里插入图片描述

5.完整代码

#include <stdio.h>
#include <malloc.h>
#define MAXSIZE 20 

//定义结构体
typedef struct LNode {
    int data;
    struct LNode *next;
} LNode, *LinkList;

LNode* SortList(LinkList A) {
    LNode *p, *tail = A, *minus = NULL,*s = NULL;
    if(!A) {
        return NULL;
    }
    p = A->next;
    while(p) {
        tail->next = p;
        s = p;
        p = p->next;
        s->next = minus;
        if(s->data >= 0) {//非负数,移动tail指针
            tail = s;
        } else {//负数
            minus = s;
        }
    }
    return minus;
}

int main() {
    //创建单链表
    LinkList A = (LinkList)malloc(sizeof(LNode));
    int a[] = {1, 2, -4, 3, 4, -1, 7, -3};
    LNode *s = NULL;
    LNode *tail = A;//tail指向尾结点
    //循环创建链表
    for(int i=0; i < sizeof(a) / sizeof(a[0]); i++) {
        s = (LNode *)malloc(sizeof(LNode));//创建新结点
        s->data = a[i];
        s->next = NULL;
        tail->next = s;
        tail = tail->next;
    }
    LinkList p = A->next;
    //打印查看原始数据
    printf("A链表的数据为:\n");
    while(p) {
        printf("%d\t", p->data);
        p = p->next;
    }
    printf("\n");
    LNode *q = SortList(A);
    printf("负数序列为:\n");
    while(q) {
        printf("%d\t", q->data);
        q = q->next;
    }
    p = A->next;
    printf("\n修改后A链表的数据为:\n");
    while(p) {
        printf("%d\t", p->data);
        p = p->next;
    }
    return 0;
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天进步一点丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值