关于链表的讨论报告-第三小组

第三小组链表讨论
• PTA题目集
4-1、删除单链表有数节点,碰到问题如下:
• 在第一个数据节点没有进行独立输入,导致答案错误。
• 建表时只申请了第一个节点的空间,对于后续节点没有向内存申请空间。
• 在完成建表后没有将最后一个数据节点的next域置为NULL,导致溢出。
• 在判断节点是否为偶数时没时对第一个数据节点为偶数时进行特殊处理导致答案错误。
解决方法:在小组讨论后,小组成员对第一个数据节点的输入进行独立操作,在建表时对节点进行内存空间申请,完成输入后将p->next域置为NULL。在删除函数里,增加一条if语句来对第一个数据节点进行判断以及操作。
源程序:

struct ListNode *createlist()
{
    int m,n;
    struct ListNode *p,*s,*head;
    head=(struct ListNode*)malloc(sizeof(struct ListNode));
    head->next=NULL;
    scanf("%d",&m);
    if(m!=-1)
    {
    head->data=m;
    p=head;
    }
    else return 0;
    scanf("%d",&m);
    while(m!=-1)
    {
        s=(struct ListNode*)malloc(sizeof(struct ListNode));
        s->data=m;
        p->next=s;
        p=s;        
        scanf("%d",&m);
    }
    p->next=NULL;
    return head;
}
struct ListNode *deleteeven(struct  ListNode *head)
{
    struct ListNode *p,*q,*lastNode=NULL;
    p=q=head;
    while(p!=NULL)
    {
        if(p->data%2==0)
        {
            if(p==head)
            {
                head=p->next;
                q=head;
                free(p);
            }
            else
            {
                q=p->next;
                free(p);
            }
        }
        else
        {
            lastNode=p;
            q=p->next;
        }
        if(lastNode!=NULL)lastNode->next=p=q;
        else p=q;
    }
    return head;
}

4-2链表逆置,碰到的问题如下:
• 仍然有成员犯了4-1中建表的错误。
• 将建表函数放入答案中,导致编译过不了。。
• 重构链表时将新表建为带有头节点的链表,与题目所给的打印函数不符合,导致输出了头节点的地址。
解决方法:(1)(2)略,经过小组讨论后,建一个不带头节点的链表来解决输出头节点地址的问题。或者直接对链表进行操作,使链表指针一一发生转向来实现逆置。
源程序:

struct ListNode *reverse( struct    ListNode *head )
{
    struct ListNode *p,*q,*r;
    p=head;
    q=NULL;
    r=NULL;
    while(p)
    {
        q=p->next;
        p->next=r;
        r=p;
        p=q; 
    }
    return r;
}

4-4求链表的倒数第m个元素,碰到的问题如下:
• 本题为有带头节点的链表,操作时没有将L移动到第一个数据节点上。
• 在统计链表中数据节点的个数时将计数变量置为1,导致后续计算所求元素位置时出现逻辑错误。
• 在统计完数据节点个数后没有将指针重新指向第一个数据节点。
• 没看清题目,返回了一个指针。
解决方法:经过小组讨论将L移动到第一个数据节点上,将计数变量的初值置为0,在统计完数据节点个数后将指针重新指向第一个数据节点,返回所求数据元素。
源程序:

ElementType Find(List L,int m)
{
    List p,q;
    int i=0,j=0,e;
    p=L;
    q=L;
    p=p->Next;
    while(p)
    {
        i++;
        p=p->Next;
    }
    p=q;
    p=p->Next;
    while(j<i-m&&p!=NULL)
    {
        j++;
        p=p->Next;
    }
    if(p==NULL)
    return ERROR;
    else
        {
            e=p->Data;
            return e;
        }
}

5-5两个有序链表序列的合并碰到的问题
• 部分成员在建表时建了有带头点的链表,导致链表合并时出现了错误。
• 打印时题目要求结尾没有多余的空格,没有进行特殊处理,导致错误。
• 没有对空链表进行处理
解决方法:建表时采用不带头节点的链表,避免没必要的麻烦。对最后一个节点打印进行独立操作。并对空链表这种情况进行处理。
源程序:

#include<stdio.h>
#include<stdlib.h>
typedef struct List
{
    int data;
    struct List *next;
} List;
List *createlist();
void printflist(List *pre);
List *sort(List *head);
List *add(List *L1,List *L2);
int main()
{
 List *L1,*L2,*L3,*L;
L1=createlist();
L2=createlist();
L3=add(L1,L2);
L=sort(L3);
printflist(L) ;
} 
List *createlist()
{
    List *L,*p,*q;
    L=(List*)malloc(sizeof(List*));
    L->next=NULL;
    p=L;
    int m;
    scanf("%d",&m);
    if(m!=-1)
    {
        L->data=m;
        p=L;
    }   
    else 
        return 0;
        scanf("%d",&m);
    while(m!=-1)
    {
        q=(List*)malloc(sizeof(List*));
        q->data=m;
        p->next=q;
        p=q;
        scanf("%d",&m);
    }
    p->next=NULL;
    return L;
}
List *add(List *L1,List *L2)
{
    List *p,*q,*pre,*r;
    p=L1->next;
    pre=L1;
    q=L2;
    r=pre;
    while(p!=NULL)
    {
    pre->next=p;
    pre=pre->next;
    p=p->next;  
    }   
    while(q!=NULL)
    {
        pre->next=q;
        pre=pre->next;
        q=q->next;
    }   
    pre->next=NULL;
    return r;
}
void printflist(List *L)
{
    while(L)
    {
        if(L->next!=NULL)
        {
        printf("%d ",L->data);
        }
        else
        printf("%d",L->data);
        L=L->next;
    }
}
List *sort(List *head)
{
    List *p,*pre,*q;
    p=head->next->next;
    head->next->next=NULL;
    while(p!=NULL)
    {
        q=p->next;
        pre=head;
        while(pre->next!=NULL&&pre->next->data<p->data)
        pre=pre->next;
        p->next=pre->next;
        pre->next=p;
        p=q;   
    } 
    return head;
}

转载于:https://www.cnblogs.com/DedSec/p/6551196.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值