• 大学实验3指导:利用单链表实现A-B


    实验目的:深入理解单链表的建立及操作

    实验内容:

    1.建立单链表AB

    2.实现主要的函数,查找、插入、删除等

    3.实现操作A-B

     

    步骤1:包含必要的函数库,对结构体LNode中的抽象数据类型ElemType进行具体定义

    1 #include <stdio.h>
    2 
    3 #include <stdlib.h>
    4 
    5 typedef int ElemType;

    步骤2:定义结构体LNode

    1 typedef struct LNode
    2 
    3 {
    4 
    5      ElemType data;
    6 
    7      struct LNode *next;
    8 
    9 }LNode, *LinkList;

    F提示LNode用于声明单链表中的一个数据结点,LinkList用于声明指向单链表中的数据结点的指针

    步骤3:定义基本的函数InitList_L()ListInsert_L()GetElem_L ()ListSize_L(),用于建立单链表AB

    步骤3.1实现函数InitList_L()。(该函数用于对单链表进行初始化,即创建头结点)

    F提示1:参数L为指向“单链表头指针”的指针,即

    LinkList *L;

    等价于

    LNode **L;

    F提示2:由于需要在函数中修改L所指向的头指针的内容(即调用InitList_L()之前,头指针为空,调用InitList_L()之后,头指针指向新创建的头结点),因此需要在L前加“*”号。

    F提示3:由于*L表示头指针的内容,因此在修改头结点的next域时,可以执行:

    (*L)->next=NULL

    由于在a为指向结构体的指针时,运算a->b等价于(*a).b,因此该语句等价于:

    (*(*L)).next=NULL;

     

     1 void InitList_L(LinkList *L)
     2 
     3 {
     4 
     5      *L=(LinkList)malloc(sizeof(LNode));
     6 
     7      if (*L==NULL)
     8 
     9          exit(-1);
    10 
    11      (*L)->next=NULL;
    12 
    13      //等价于(*(*L)).next=NULL;                                              
    14 
    15 }

    步骤3.2实现函数ListInsert_L ()。(在指定位置上插入新元素)

     1 int ListInsert_L(LinkList L,int i,ElemType e)
     2 
     3 { 
     4     LNode *p,*s;
     5     int j;
     6     p=L;
     7     j=0;
     8     while(p&&j<i-1)
     9     {
    10         p=p->next;++j;
    11     }
    12     if(!p||j>i-1) 
    13         return 0;
    14      s=(LinkList)malloc(sizeof(LNode));
    15      s->data=e;
    16      s->next=p->next;
    17      p->next=s;
    18      return 1;
    19  }

    步骤3.3GetElem_L()。(返回顺序表中指定位置上的元素)

     1 int GetElem_L(LinkList L, int i, ElemType *e)
     2 {
     3     LinkList p;
     4     int j=1;
     5     p=L->next;
     6     while(p&&j<i)
     7     {
     8         p=p->next; 
     9         ++j;
    10     }
    11     if(!p||j>i) 4
    12         return 0;
    13     *e=p->data;
    14     return 1;  
    15 }

    步骤3.4ListSize_L()。(返回单链表的长度)

     

     1 int ListSize_L(LinkList L)
     2 {
     3     LNode *p;
     4     int count=0;
     5     p=L;
     6     while(p->next!=NULL)
     7     {
     8         p=p->next;
     9         count++;
    10     }
    11     return count;  
    12 }

     

     

    步骤4:建立线性表AB,并输出其中的元素

    F提示:采用静态方式创建A=(3,5,8,11)B=(2,6,8,9,11,15,20)

     1 int main()
     2 {
     3     int i,flag,e;
     4     //定义两个头指针
     5     LinkList A,B;
     6     //测试函数GetElemPointer_L()
     7     LNode *p;
     8     /*初始化单链表A,将头指针A的地址(即指向A的指针)传入*/
     9     InitList_L(&A);
    10     /*初始化单链表B,将头指针B的地址(即指向B的指针)传入*/ 
    11     InitList_L(&B);
    12     /*为单链表A填充数据*/
    13     ListInsert_L(A,1,3);
    14 15     ListInsert_L(A,4,11);
    16     /*为单链表B填充数据*/
    17     ListInsert_L(B,1,2);
    18 19     ListInsert_L(B,7,20);
    20     /*输出单链表A*/
    21     printf("单链表A中的元素为:
    "); 
    22     for(i=1;i<=ListSize_L(A);i++)
    23     {
    24         flag=GetElem_L(A,i,&e);
    25         if(flag)
    26             printf("%4d",e);
    27     }
    28     printf("
    ");
    29     /*输出单链表B*/
    30     printf("单链表B中的元素为:
    "); 
    31     for(i=1;i<=ListSize_L(B);i++)
    32     {
    33         flag=GetElem_L(B,i,&e);
    34         if(flag)
    35         printf("%4d",e);
    36     }
    37     printf("
    ");
    38 }

    步骤4的输出结果

     

    步骤5:实现函数ListDelete_L()。(用于删除指定位置上的元素)

    F提示:该函数的声明为:

    1 int ListDelete_L(LinkList *L,int i, ElemType *e)

    步骤6:测试函数ListDelete_L()

     1     flag=ListDelete_L(&B,7,&e);
     2     if(flag)
     3     printf("被删除的元素为:%4d",e);
     4     printf("
    ");
     5     printf("单链表B中的剩余元素为:
    "); 
     6     for(i=1;i<=ListSize_L(B);i++)
     7     {
     8         flag=GetElem_L(B,i,&e);
     9         if(flag)
    10         printf("%4d",e);
    11     }
    12     printf("
    ");


    步骤6的输出结果

    步骤7:实现函数LocateElem_L ()

    LocateElem_L():返回给定元素在单链表中的位置(序号)。注意:头结点的序号为0

    F提示:首先,令p指向单链表的表头结点,即L->next。若单链表为空,即L->next==NULL,则返回0。否则,对单链表进行遍历,并返回匹配结点的位置。最后,若最终没有找到,则返回0

    该函数声明为:

    1 int LocateElem_L(LinkList L, ElemType e);

    步骤8:测试函数LocateElem_L()

    1 flag=LocateElem_L(B,15);
    2 printf("元素15在单链表B中的位置为:%4d
    ",flag); 


    步骤8的输出结果

    步骤9:实现函数GetElemPointer_L()。(返回指向单链表中第i个元素的指针)

    F提示:首先,若单链表为空,即L->next==NULL,则返回空指针。接下来,若参数i非法,则返回空指针。然后,对单链表进行遍历,并返回匹配结点的指针。最后,若最终没有找到,则返回空指针。

    该函数声明为:

    1 LNode *GetElemPointer_L(LinkList L,int i);

    步骤10:测试函数GetElemPointer_L()

    1 p=GetElemPointer_L(A,3);
    2 printf("单链表A中的第3个元素为:%4d
    ",p->data);

    步骤10的输出结果

    步骤11:实现函数DelElem_L()(实现A-B)。

    F提示:利用循环遍历顺序表B。在每轮循环中,先利用函数GetElemPointer_L()取得指向B中的当前结点的指针(假设该结点指针保存在p中),再利用函数LocateElem_L()检查中A是否存在数据域等于p->data的结点,若存在则返回匹配结点的位置pos。最后,利用函数ListDelete_L()删除所匹配的结点(即A中的第pos个结点)。

    函数DelElem_L()的声明如下:

    1 void DelElem_L(LinkList A,LinkList B);

    步骤12:测试函数DelElem_L()的功能

      

    1     DelElem_L(A,B);//执行A-B
    2     printf("单链表A中的剩余元素为:
    "); 
    3     for(i=1;i<=ListSize_L(A);i++)
    4     {
    5         flag=GetElem_L(A,i,&e);
    6         if(flag)
    7         printf("%4d",e);
    8     }
    9     printf("
    ");


    步骤12的输出结果

    思考题

    1.将有关单链表的所有基本函数组织成单独的文件“LinkList.h”,然后利用include命令调用该文件。

     1 /*删除指定位置上的元素*/
     2 int ListDelete_L(LinkList *L,int i, ElemType *e) {
     3     LNode *p,*q;
     4     p=*L;
     5     int j=0;
     6     while(p->next&&j<i-1) {
     7         p=p->next;
     8         ++j;
     9     }
    10     if(!(p->next)||j>i-1) return 0;
    11     q=p->next;
    12     p->next=q->next;
    13     *e=q->data;
    14     free(q);
    15     return 1;
    16 }
    17 
    18 /*返回给定元素在单链表中的位置*/
    19 int LocateElem_L(LinkList L, ElemType e) {
    20     LNode *p;
    21     int i;
    22     if(L->next==NULL)
    23         return 0;
    24     p=L->next;
    25     i=1;
    26     while(p) {
    27 
    28         if(p->data==e)
    29             return i;
    30         else {
    31             p=p->next;
    32             i++;
    33         }
    34         if(!p) return 0;
    35     }
    36 }
    37 
    38 /*返回指向单链表中第i个元素的指针*/
    39 /*若找到第i个结点,则返回指向该结点的指针;否则,返回空指针*/
    40 LNode *GetElemPointer_L(LinkList L,int i) {
    41     LNode *p;
    42     int j;
    43 //若单链表为空
    44     if(L->next==NULL)
    45         return NULL;
    46 //若参数非法
    47     if(i<1)
    48         return NULL;
    49     p=L;
    50     j=0;
    51     while(p->next!=NULL&&j<i) {
    52         p=p->next;
    53         j++;
    54     }
    55     if(j==i)
    56         return p;
    57     else
    58         return NULL;
    59 }
    60 
    61 void DelElem_L(LinkList A,LinkList B) {
    62     int i,pos,flag;
    63     ElemType e;
    64     LNode *p;
    65     for(i=1; i<=ListSize_L(B); i++) {
    66         p=GetElemPointer_L(B,i);//p指向单链表B中存在第i个结点
    67         if(p) { //若单链表B中存在第i个结点
    68             pos=LocateElem_L(A,p->data);//若A中存在相同的结点,则用返回其在A中的位置
    69             if(pos>0)//若存在,则在A中删除该元素
    70                 ListDelete_L(&A,pos,&e);
    71             /*
    72             {flag=ListDelete_L(&A,pos,&e);
    73              if(flag)
    74              printf("被删除的元素为:%4d
    ",e);
    75              }
    76              */
    77         }
    78     }
    79 }
    昔日我曾苍老,如今风华正茂(ง •̀_•́)ง
  • 相关阅读:
    结对作业——WordCount进阶版
    个人作业2——WordCount
    软工网络16个人作业1
    request内置对象在JSP
    Servlet处理表单
    Web-JSP表单字符验证
    201621123037 《Java程序设计》第14周学习总结
    201621123037 《Java程序设计》第13周学习总结
    转载 写了 35 年代码的老程序员的最大遗憾
    设计OA系统的用户-角色-权限分配
  • 原文地址:https://www.cnblogs.com/lgqrlchinese/p/10104461.html
Copyright © 2020-2023  润新知