1. 问题描述:
设计一个算法,将一个头结点为A的单链表(其数据域为整数)分解成两个单链表A和B,使得A链表只含有原来链表data域为奇数的节点,而B链表只含有原链表中data域为偶数的节点,而且保持原来的顺序
2. 思路分析:
① 这个问题不是在线网上评测系统上的,所以没有标准的输入和输出数据,只能够通过简单的数据来判断程序的逻辑是否正确,首先在将原来的链表分开之前,我们需要将创建出一个单链表,这里使用一个给定的数组来创建出单链表这样的话测试起来比较方便,也可以修改为在控制台输入数字来创建歘相应的链表
② 创建出单链表之后那么需要扫描整个链表,判断当前节点的数据域是否是偶数,假如是偶数的话那么将节点插入到链表B中,并且修改原来链表的指针指向问题,也就是在原来链表中删除这个节点(修改前一个指针的指向,为指向下一个节点的下一个节点)
在删除之前我们需要使用一个临时的变量来进行保存一下需要删除的节点的,因为我是需要将此节点插入到链表B中的,所以需要保存起来,然后在原来的链表中修改指针的指向,将待删除节点的前一个节点的指针指向待删除节点的后一个节点
为了方便我们可以在循环的时候设置成判断条件是p->next!=NULL这样我们就可以知道待删除节点的前驱节点是谁了
③ 我感觉主要是链表之间的指针指向的修改,在不清楚元素之间的指向的时候那么我们可以画出具体的图来帮助理解,写多了程序这些指针的指向自然就比较清楚了
3. 下面是具体的代码:
#include<iostream>
#include<malloc.h>
using namespace std;
typedef struct node{
int data;
node *next;
}LNode;
LNode *L;
LNode* create(LNode *L, int arr[], int n){
L = (LNode*)malloc(sizeof(LNode));
L->next = NULL;
LNode *p = L;
for(int i = 0; i < n; ++i){
LNode *newNode = (LNode*)malloc(sizeof(LNode));
newNode->next = NULL;
newNode->data = arr[i];
//头插法
p->next = newNode;
p = p->next;
}
return L;
}
//分离的方法
void spilt(LNode *L, LNode *B){
LNode *p = L;
B = (LNode*)malloc(sizeof(LNode));
B->next = NULL;
LNode *q = B;
LNode *r;
while(p->next != NULL){
if(p->next->data % 2 == 0){
//下面处理的是取下链表中的偶数节点插入到链表中
//偶数的时候取出来插入到链表B中
r = p->next;
p->next = p->next->next;
//q指针向下移动
q->next = r;
r->next = NULL;
q = q->next;
}else{
p = p->next;
}
}
//输出链表A的内容
LNode *s = L;
while(s->next != NULL){
printf("%d ", s->next->data);
s = s->next;
}
cout << endl;
//输出链表B的内容
s = B;
while(s->next != NULL){
printf("%d ", s->next->data);
s = s->next;
}
}
int main(void){
int arr[12] = {12, 43, 2, 10, 100, 89, 11, 56, 45, 34, 77, 11};
LNode *head = create(L, arr, 12);
LNode *B;
spilt(head, B);
return 0;
}