R6-1 LinkList1-摘取A链表中值位于[min,max]中的结点到B链表中【有题解视频,可本地编译器调试】<<<<个人学习记录

R6-1

R6-1

带头结点的单链表结点定义如下:

函数接口定义:

裁判测试程序样例:

输入样例:

输出样例:

个人参考代码:


在一个带头结点的单链表A中,头指针为a,编写算法CountItems( )获取A中所有数据域大于等于min,而小于等于max的链点,将所得链点插入一个新的单链表B,要求B链表除了头结点b可以新开辟空间外,其余链点均利用A表的链点,最终打印出新链表B,并且打印出新链表元素在原链表中的序号。

带头结点的单链表结点定义如下:

 
typedef int DataType;
typedef struct Node
{
    DataType data;      // data域用于存储数据元素
    struct Node *next;  // next域用于存放指向其后继的指针
}LNode, *PNode, *LinkList;  // LinkList为头指针

函数接口定义:

函数接口如下:
int CountItems( LinkList a , LinkList *b , LinkList *no, DataType min , DataType max );

其中 a ,b , no,min,max都是用户传入的参数。 a是原始链表A的头指针,*b是新链表B的头指针,*no是存储B中元素在A中下标的链表头指针,minmax是数据域区间上下限。

裁判测试程序样例:

 

#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
typedef struct Node
{
    DataType data;
    struct Node* next;
}LNode, * PNode, * LinkList;
int InitLinkList(LinkList* head)
{ // 初始化单链表,开辟头结点
    *head = (LinkList)malloc(sizeof(LNode));
    if (!head)
    {
        printf("初始化链表错误!\n");
        return 0;
    }
    (*head)->next = NULL;
    return 1;
}
PNode LinkListInsert(LinkList h, int pos, DataType x)
{ // 在单链表h的第pos个位置插入x值的元素
    PNode p = h, q;
    int i = 0;
    while (p && i < pos - 1)
    {
        p = p->next;
        i++;
    }
    if (!p || i > pos - 1)
    {
        printf("插入位置不合法!\n");
        return NULL;
    }
    q = (PNode)malloc(sizeof(LNode));
    if (!q)
    {
        printf("不能生成新结点\n");
        return NULL;
    }
    q->data = x;
    q->next = p->next;
    p->next = q;
    return q;
}
void DestroyLinkList(LinkList h)
{ // 销毁单链表
    PNode p = h->next;
    while (h)
    {
        p = h;
        h = h->next;
        free(p);
    }
}
void TraverseLinkList(LinkList h)
{ // 遍历单链表
    PNode p = h->next;
    while (p)
    {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}
int BnotinA(LinkList a, LinkList b)
{ // 判链表B的链点是否来自链表A
    PNode pb = b->next;
    PNode pa = a->next;
    if (!pa)
    {
        return 1;
    }
    if (!pb)
    {
        return 1;
    }
    while (pa)
    {
        if ((DataType)pb != pa->data)
        {
            pa = pa->next;
            continue;
        }
        return 0;
    }
    return 1;
}
/* 本题要求函数 */
int CountItems(LinkList a, LinkList* b, LinkList* no, DataType min, DataType max);
int main()
{
    LinkList h, s, aa1, xb, pa = NULL;
    DataType x, lo, hi;
    char ch;
    int pos = 1;
    InitLinkList(&h);
    InitLinkList(&aa1);
    InitLinkList(&s);
    InitLinkList(&xb);
    do
    {
        scanf("%d", &x);  // 某些编译器要求此处改为scanf_s
        pa = LinkListInsert(h, pos, x);
        if (pa != NULL)
        {
            LinkListInsert(aa1, pos, (DataType)pa);
        }
        pos++;
    } while ((ch = getchar()) != '\n');
    scanf("%d%d", &lo, &hi);  // 某些编译器要求此处改为scanf_s
    if (CountItems(h, &s, &xb, lo, hi) == 1)
    {
        if (BnotinA(aa1, s) != 1)
        {
            printf("单链表B是:\n");
            TraverseLinkList(s);
            printf("单链表B中元素位于单链表A中的位置是:\n");
            TraverseLinkList(xb);
        }
    }
    else
    {
        printf("A链表中没有位于[%d,%d]区间的数据!\n", lo, hi);
    }
    DestroyLinkList(h);
    DestroyLinkList(s);
    DestroyLinkList(xb);
    return 0;
}    
/* 请在这里填写答案 */

输入样例:

23 56 21 42 23 89 30 64 23
30 45

输出样例:

单链表B是:
42 30 
单链表B中元素位于单链表A中的位置是:
4 7 

个人参考代码:

int CountItems( LinkList a , LinkList *b , LinkList *no, DataType min , DataType max )
{
	PNode pre = a;//前一梿点指针
	PNode p = a->next;//当前指针,方便理解的话可以用cur(与老师讲的一致)
	PNode b_tail = *b;
	PNode no_tail = *no;//序号链表
	PNode p_no;
	
	int cnt = 0;
	int flag = 0;
	
	while(p)
	{
		if (p->data >= min && p->data <= max)
		{
			flag = 1;//标记是否进入过循环,来判断是否有[min, max]区间的数
			pre->next = p->next;
			p->next = NULL;
			b_tail->next = p;
			b_tail = p;//尾插法
			p = pre->next;//跳回原链表A
			cnt++;
			p_no = (PNode)malloc(sizeof(LNode));/*malloc 开辟空间 存放序号,
因为不知道序号多少个,所以动态存储*/
			p_no->data = cnt;
			p_no->next = NULL;
			no_tail->next = p_no;
			no_tail = p_no;//尾插法
		}
		else
		{
			pre = pre->next;//不符条件,就后移
			p = p->next;
			cnt++;//cnt 即为所在序号,遍历链表,可以用来替代
		}
	}
	if (flag == 1)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值