线性表实验六 将单链表按基准划分
目的: 掌握单链表的应用和算法设计。
内容: 编写一个程序,以给定值x为基准将单链表分割为两部分,所有小于x的结点排在大于或等于x的结点之前。你应当 保留 两个分区中每个节点的初始相对位置。

单链表为:{1, 4, 3, 2, 5, 2}, x = 3
以3为基准划分后,单链表为:{1, 2, 2, 4, 3, 5}。
typedef char ElemType;
typedef struct LNode {
ElemType data;
struct LNode *next; //指向后继结点
} LinkNode; //单链表结点类型
#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef struct LNode {
ElemType data;
struct LNode *next; //指向后继结点
} LinkNode; //单链表结点类型
/**
* 尾插法建立单链表:裁判实现
*/
void CreateListR(LinkNode *&L, ElemType a[], int n);
/**
* 输出线性表: 每个数据后面一个空格:裁判实现
*/
void DispList(LinkNode *L);
/**
* 将L中所有数据结点按x进行划分。
* 所有小于x的结点排在大于等于x的结点前面。
* 必须保证两个分区中每个节点的初始相对位置。
*/
void Split(LinkNode *&L, ElemType x);
int main()
{
int n;
scanf("%d", &n);
ElemType a[n];
for (int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
LinkNode *L;
CreateListR(L, a, n);
printf("L:"); DispList(L);
ElemType x;
scanf("%d", &x);
printf("以%d进行划分\n", x);
Split(L, x);
printf("L:"); DispList(L);
return 0;
}
/* 请在下面书写程序代码 */
思路是先找到符合要求大于等于x的第一个节点point并保存它的前驱节点pre
然后从这个基点开始往后找小于x的节点,如果找到就将这个节点插入到基点和它的前驱节点中间,并将前驱节点的指针迁移到插入的节点上,同时可以设计一个指针end指向基点,如果遇到等于大于x的节点就将它往后移,这样每次插入后可以从end指针开始往后找,减少查找时间
/**
* 将L中所有数据结点按x进行划分。
* 所有小于x的结点排在大于等于x的结点前面。
* 必须保证两个分区中每个节点的初始相对位置。
*/
void Split(LinkNode *&L, ElemType x){
if(L->next == NULL)return;
//找到第一个基点
//point基点 pre基点的前驱节点
struct LNode* point = L,*pre;
while(point->next != NULL){
pre = point;
point=point->next;
//找到节点就结束point停止在第一个大于等于x的节点
if(point->data >= x)break;
}
//将小于基点的的节点放在前面
struct LNode* q = point,*end = point;
while(q->next != NULL){
q = q->next;
if(q->data < x)
{
end->next = q->next;
pre->next = q;
q->next = point;
pre = q;
q = end;
//DispList(L);
//printf("\n");
}
else {
end = q;
//DispList(L);
//printf("\n");
}
}
}