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;
}