6-3 将单链表按基准划分

线性表实验六 将单链表按基准划分

目的: 掌握单链表的应用和算法设计。

内容: 编写一个程序,以给定值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");
             }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值