实验二 链表的基本操作

来源:互联网 发布:北京pk10网络关注平台 编辑:程序博客网 时间:2024/06/06 11:42

实验二 链表的基本操作

一、实验目的
1.掌握线性表的链式存储结构的表示和实现方法。
2.掌握链表基本操作的算法实现。

二、实验内容
1.建立单链表,并在单链表上实现插入、删除和查找操作(验证性内容)。
2.计算已知一个单链表中数据域值为一个指定值x的结点个数(应用性设计内容)。
3.建立双向循环链表,并在双向循环链表上实现插入、删除和查找操作(选做内容)。

三、实验要求
1.建立单链表,并在单链表上实现插入、删除和查找操作。
编程实现如下功能:
(1)根据输入的一系列整数,以0标志结束,用头插法建立单链表,并输出单链表中各元素值,观察输入的内容与输出的内容是否一致。
(2)在单链表的第i个元素之前插入一个值为x的元素,并输出插入后的单链表中各元素值。
(3)删除单链表中第i个元素,并输出删除后的单链表中各元素值。
(4)在单链表中查找第i个元素,如果查找成功,则显示该元素的值,否则显示该元素不存在。
2.计算已知一个单链表中数据域值为一个指定值x的结点个数。
⑴ 从键盘输入若干个整数,以此序列为顺序建立一个不带头结点的单链表;
⑵ 输出此单链表中的各个数据元素值;
⑶ 给定一个x的具体整数值,计算并返回此单链表中数据域值为x的结点个数值。
3.建立双向循环链表,并在双向循环链表上实现插入、删除和查找操作。
(1)输入链表的长度和各元素的值,用尾插法建立双向循环链表,并输出链表中各元素值,观察输入的内容与输出的内容是否一致。
(2)在双向循环链表的第i个元素之前插入一个值为x的元素,并输出插入后的链表中各元素值。
(3)删除双向循环链表中第i个元素,并输出删除后的链表中各元素值。
(4)在双向循环链表中查找值为x元素,如果查找成功,则显示该元素在链表中的位置,否则显示该元素不存在。

四、详细程序清单

//1.单链表 #include <stdio.h>  #include <stdlib.h>  typedef struct LNode{int data;struct LNode *next;}LNode,*LinkList;LinkList head,k;void Show(LinkList t)//显示 {       printf("当前链表元素为:");    t=t->next;     while(t!=NULL)      {          printf("%d ",t->data);          t=t->next;      }     printf("\n");  }  void CreateHead(LinkList &L)//头插法创建单链表 {    head=(LinkList)malloc(sizeof(LNode));      head->next=NULL;    head->data=NULL;    LinkList p,t;    int x;    t=head;    printf("请输入数值,以0结束\n");    while(~scanf("%d",&x),x)    {         p=(LinkList)malloc(sizeof(LNode));          p->data=x;          p->next=t->next;         t->next=p;          }} void CreateTail(LinkList &L)//尾插法创建单链表并显示 {    k=(LinkList)malloc(sizeof(LNode));      k->next=NULL;    k->data=NULL;    LinkList last,t,s;    int x;    last=k;    s=k;    printf("请输入数值,以0结束\n");    while(~scanf("%d",&x),x)    {        t=(LinkList)malloc(sizeof(LNode));        t->data=x;        t->next=NULL;        if(head==NULL){head=t;last=t;}        else{last->next=t;last=t;}          } }int Insert(LinkList &L,int i,int e)//插入 {    LinkList t,p;    int j=1;    t=head;    if(i<1){printf("插入错误\n");return 0;}    if(i==1) //插入位置在表头     {        p=(LinkList)malloc(sizeof(LNode));         p->data=e;        p->next=t->next;        head->next=p;        printf("插入成功\n");        return 0;       }       while(j<i-1&&L)    {            t=t->next;            j++;            if(t==NULL)            {                printf("插入错误\n");                return 0;            }    }    //插在非表头     t=t->next;    p=(LinkList)malloc(sizeof(LNode));     p->data=e;    p->next=t->next;    t->next=p;    printf("插入成功\n");}int Delete(LinkList &L,int i)//删除 {    LinkList p,t;    int j=0;    p=head;    if(i<1){printf("删除失败\n");return 0;}    while(j<i-1&&L)    {            p=p->next;            j++;            if(p==NULL)            {                printf("删除失败\n");                return 0;            }       }       t=p->next;    p->next=t->next;    printf("删除成功\n");    free(t);    }int Secrch(LinkList &L,int i)//查找 {    LinkList p;    int j=0,e;    p=head;    if(i<1){printf("查找失败,该元素不存在\n");return 0;}    while(j<i&&L)    {            p=p->next;            j++;            if(p==NULL)            {                printf("查找失败,该元素不存在\n");                return 0;            }       }    e=p->data;    printf("查找成功,第%d个元素为%d\n",i,e); }void Calculate(LinkList &L,int i){    LinkList p;    p=k;    int count=0;    while(p->next!=NULL)    {        if(i==p->data) count++;         p=p->next;    }    printf("元素%d%d个\n",i,count);   }int main()  {      LinkList L;    int select,i,e;     while(1)      {           printf("1.头插法建表 \t2.尾插法建表 \t3.插入 \t4.删除 \t5.查找 \t6.统计\n");           scanf("%d",&select);          switch(select)          {            case 1:              CreateHead(L);            Show(head);              break;          case 2:             CreateTail(L);            Show(k);            break;            case 3:             printf("输入位置和要插入的元素\n");            scanf("%d%d",&i,&e);            Insert(L,i,e);            Show(head);            break;         case 4:             printf("输入要删除的元素的位置\n");            scanf("%d",&i);            Delete(L,i);            Show(head);            break;        case 5:              printf("输入要查找的元素的位置\n");             scanf("%d",&i);             Secrch(L,i);             break;        case 6:             printf("输入要统计的元素值\n");            scanf("%d",&i);            Calculate(L,i);            break;        case 7:              return 0;          default:             printf("输入错误\n");            break;         }      }      return 0;  }  
//2.双向循环链表 DC:Double Circular#include <stdio.h>  #include <stdlib.h> typedef struct DCLNode{int data;struct DCLNode *prior;struct DCLNode *next;}DCLNode,*DCLinkList;DCLinkList w;//尾 void Create(DCLinkList &L,int n){    DCLinkList p,t;    int x;    t=L;    scanf("%d",&x);    while(1)    {        n--;        if(!n){t=p;break;}         p=(DCLinkList)malloc(sizeof(DCLNode));        t->data=x;        t->next=p;        p->prior=t;        scanf("%d",&x);        p->data=x;        t=p;    }    L->prior=t;    t->next=L;    w=t;}void Show(DCLinkList L){    DCLinkList p;    printf("当前链表元素为:");    for(p=L;p->next!=L;p=p->next)    {        printf("%d ",p->data);    }    printf("%d ",p->data);    printf("\n");   }int Insert(DCLinkList &L,int i,int e)//插入 {    DCLinkList t,p;    int j=1;    t=w;    if(i<1){printf("插入错误\n");return 0;}      while(j<=i-1)    {            t=t->next;            j++;    }    p=(DCLinkList)malloc(sizeof(DCLNode));     p->data=e;    p->next=t->next;    t->next=p;    p->prior=t;    printf("插入成功\n");}int Delete(DCLinkList &L,int i)//删除 {    DCLinkList p,t;    int j=0;    p=w;    if(i<1){printf("删除失败\n");return 0;}    while(j<i-1)    {            p=p->next;            j++;        }       t=p->next;    p->next=t->next;    t->next->prior=p;    printf("删除成功\n");    free(t);    }int Secrch(DCLinkList &L,int e)//查找 {    DCLinkList p;    int j=1;    p=w->next;    while(1)    {            if(p->data==e){printf("查找成功,%d元素的位置为%d\n",e,j);return 0;}            if(p==w){printf("查找失败,该元素不存在\n");return 0;}            p=p->next;            j++;    }}int main()  {      DCLinkList L;    int select,i,e;    L=(DCLinkList)malloc(sizeof(DCLNode));     L->data=NULL;    L->next=L;    L->prior=L;    while(1)      {           printf("1.建表 \t2.插入 \t3.删除 \t4.查找\n");           scanf("%d",&select);          switch(select)          {            case 1:             printf("输入链表长度\n");            scanf("%d",&i);            printf("输入各元素的值\n");            Create(L,i);            Show(w->next);              break;            case 2:             printf("输入位置和要插入的元素\n");            scanf("%d%d",&i,&e);            Insert(L,i,e);            Show(w->next);            break;         case 3:             printf("输入要删除的元素的位置\n");            scanf("%d",&i);            Delete(L,i);            Show(w->next);            break;        case 4:              printf("输入要查找的元素\n");             scanf("%d",&i);             Secrch(L,i);             break;        case 5:              return 0;          default:             printf("输入错误\n");            break;         }      }      return 0;  }  

五、程序运行结果
1.单链表:
这里写图片描述

2.双向循环链表:
这里写图片描述

六、实验心得体会
1.进行除Create操作外的操作时,单链表的head最好不要变;
2.上课的时候没有理解为什么head指针的data要为NULL,经过实际操作后发现了头指针为空时,便于遍历、插入、查找等操作;
3.双向循环链表中的节点都不为空,在遍历等操作的时候和单链表有所不同,可以从尾指针->next开始;
5.错误很多,调试很烦,要有耐心。

阅读全文
0 0
原创粉丝点击