Linked list operation experiment

Linked list operation experiment

Insert picture description here

1. Experiment name and nature

Insert picture description here

2. The purpose of the experiment

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

3. Experimental content

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

Fourth, the experimental software and hardware environment requirements

硬件环境要求:PC机(单机)
使用的软件名称、版本号以及模块:
Windows环境下的TurboC2.0以上或VC++ 等。

Five, knowledge preparation

前期要求熟练掌握了C语言的编程规则、方法和单链表和双向链表的基本操作算法。

Six, confirmatory experiment

1. Experimental requirements
编程实现如下功能
(1)根据输入的一系列整数,以0标志结束,用头插法建立单链表,并输出单链表中各元素值,观察输入的内容与输出的内容是否一致。

(2) Insert an element with a value of x before the i-th element of the singly linked list, and output the value of each element in the inserted singly linked list.
(3) Delete the i-th element in the singly linked list, and output the value of each element in the deleted singly linked list.
(4) Find the i-th element in the singly linked list. If the search is successful, the value of the element is displayed, otherwise the element does not exist.

2. Experiment related principles:

The chain storage structure of the linear table uses a group of arbitrary storage units to sequentially store the elements in the linear table. This group of storage units can be continuous or discontinuous. In order to reflect the logical relationship between each element in the linear table, for each data element, in addition to storing its own data value, one or more pointer fields need to be added. The value of each pointer field is called a pointer , Also known as chain, it is used to indicate the storage address of its predecessor or successor in the linear table. These two parts together form a storage image of a data element, called a node, and several nodes are linked into a linked list. If a node contains a linked list with only one pointer, it is called a singly linked list. The storage structure of a singly linked list is described as follows:

typedef   struct  Lnode {
    
    
Elemtype   data;/*数据域*/
    struct  Lnode  *next;/*指针域*/
}LNODE,*Linklist; /*其中LNODE为结点类型名,Linklist为指向结点的指针类型名*/

[Core algorithm tips]

1. The basic steps of the linked list establishment operation: the linked list is a dynamic structure, it does not need to allocate space, so the process of creating the linked list is a process of "inserting one by one" of the nodes. First create an empty singly linked list with only head nodes, then generate new nodes in turn, and then continuously insert them into the head or tail of the linked list, which are called "head insertion method" and "tail insertion method" respectively.
2. The basic steps of the linked list search operation: because the linked list is a "sequential access" structure, to find the i-th element in the linked list of the leading node, you must start from the first node and follow the subsequent pointers to "number" in order, Until the point reaches the i-th node, if the search is successful, use e to return the value of the i-th element. The head node can be regarded as the 0th node.
3. The basic steps of the linked list insertion operation: first determine the position to be inserted, if the insertion position is legal, then generate a new node, and finally insert the new node into the specified position by modifying the chain.
4. The basic steps of the linked list delete operation: first determine the location of the node to be deleted, if the location is legal, then modify the chain to "unload" the deleted node from the linked list, and finally release the space of the deleted node.

[Description of core algorithm]

void  creat1(Linklist &L)  /*输入一系列整数,以0标志结束,将这些整数作为data域并用头插法建立一个带头结点的单链表的函数*/
{
    
       L=(Linklist)malloc(sizeof(LNODE));/*生成头结点*/
    L->next=NULL;/*头结点的指针域初始为空*/
    scanf("%d",&node);
while(node!=0)
      {
    
     p=(Linklist)malloc(sizeof(LNODE));/*为一个新结点的分配空间*/
        p->data=node; /*为新结点数据域赋值*/
        p->next=L->next;/*新结点指针域指向开始结点*/
        L->next=p;  /*头结点指针域指向新结点,即新结点成为开始结点*/
scanf("%d",&node);
}    
}
void  creat2(Linklist &L) /*输入一系列整数,以0标志结束,将这些整数作为data域并用尾插法建立一个带头结点的单链表的函数*/
 {
    
       L=(Linklist)malloc(sizeof(LNODE));/*为头结点分配空间*/
     L->next=NULL; /*头结点的指针域初始为空*/
     r=L;  /*尾指针初始指向头结点*/
scanf("%d",&node);
while(node!=0)
       {
    
     p=(Linklist)malloc(sizeof(LNODE));/*为一个新结点分配空间*/
         p->data=node; /*新结点数据域赋值*/
         p->next=NULL; /*新结点指针域为空*/
         r->next=p;/*尾结点指针域指向新结点*/
         r=p;   /*尾指针指向新结点,即新结点成为尾结点*/
scanf("%d",&node);
 }
}
       status list_search(Linklist L, int i;Elemtype &e)
            /*在带头结点的单链表L中查找第i个元素,如果查找成功则用e返回其值*/
{
    
      p=L->next;  /*使指针p指向第1个元素结点*/
j=1;        /*计数器赋初值为1*/
while (p&& j<i)  /*顺着后继指针查找第i个元素结点*/
 {
    
     p=p->next;
     j++;
}
if (!p&& j>i)
 return ERROR;  /*如果i值不合法,即i值小于1或大于表长,则出错*/
e=p->data;    /*如果第i个元素存在,则将该元素值赋给e*/
return OK;
            }
status list_insert(Linklist &L,int i;Elemtype x) 
/*在带头结点的单链表L中第i个位置之前插入新元素x*/
           {
    
     p=L;   j=0;
             while(p!=NULL&&j<i-1) /*寻找插入位置,并使p指向插入位置的前驱结点,即L中的第i-1个位置*/
               {
    
     p=p->next; 
        ++j;
}
             if(p==NULL||j>i-1)
               return ERROR; /*若位置不正确,即i小于1或大于表的长度加1,则出错*/
             s=(Linklist)malloc(sizeof(LNODE)); /*分配一个新结点的空间*/
             s->data=x;   /*为新结点数据域赋值*/
              /*下面两条语句就是完成修改链,将新结点s插入到p结点之后*/
 s->next=p->next;  /*新结点指针域指向p的后继结点*/
             p->next=s;   /*新结点成为p的后继结点*/
             return OK;
}
status  list_delete(Linklist &L,int i,Elemtype &x)
/*在带头结点的单链表L中,删除第i个元素结点,并用x返回其值*/
          {
    
     p=L;j=0;
            while(p->next!=NULL&&j<i-1) /*寻找被删结点,并使p指向被删结点的前驱*/
              {
    
     p=p->next; 
++j; 
}
            if (p->next==NULL||j>i-1)
                   return ERROR;   /*若位置不正确,即i小于1或大于表长,则出错*/
            q=p->next;     /* q指向p的后继结点*/
            p->next=q->next;  /*q的后继结点成为p的后继结点*/
            x=q->data;   /*用x返回第i个位置的元素*/
free(q);   /*释放q所指的被删结点的空间*/
return OK;
}
3. Source code reference
#include <stdio.h>
#include <malloc.h>
typedef struct Lnode
   {
    
     int data;
     struct Lnode *next;
   } LNODE,*Linklist;
Linklist creat(Linklist L)  /*单链表建立函数 */
{
    
    int node; Linklist p;
 L=(Linklist)malloc(sizeof(LNODE));
 L->next=NULL;
 printf("\nplease input the node(end with 0):\n  ");
       /*请求输入线性表中各个元素,以0结束*/
 scanf("%d",&node);
 while(node!=0)
   {
    
    p=(Linklist)malloc(sizeof(LNODE));
    if (!p)   exit();
    p->data=node;
    p->next=L->next;
    L->next=p;
    scanf("%d",&node);
   }
 return L;
}
Linklist insert(Linklist L,int i,int x)  /*单链表插入函数*/
{
    
     int j;Linklist p,s;
  p=L; j=0;
  while (p!=NULL&&j<i-1)
    {
    
     p=p->next;
      ++j;
    }
  if (p==NULL||j>i-1)
    printf("\n ERROR position!\n");
  else
    {
    
     s=(Linklist)malloc(sizeof(LNODE));
      s->data=x;
      s->next=p->next;
      p->next=s;
    }
  return L;
}
Linklist delete(Linklist L,int i)  /*单链表删除函数*/
{
    
     int j,x; Linklist p,q;
  p=L; j=0;
  while(p->next!=NULL&&j<i-1)
   {
    
    p=p->next;
    ++j;
   }
  if(p->next==NULL||j>i-1)
    printf("\n ERROE position!\n");
  else
    {
    
     q=p->next;
      p->next=q->next;
      x=q->data;
      printf("the delete data is:%d\n",x);
      free(q);
    }
  return L;
}
int search(Linklist L, int i) /*单链上的查找函数*/
{
    
     Linklist p; int j;
  p=L->next;
  j=1;
  while (p&& j<i)
   {
    
     p=p->next;
     j++;
   }
  if (!p&& j>i)
     return 0;   /*如果i值不合法,即i值小于1或大于表长,则函数返回0值*/
  else
     return(p->data);    /*否则函数返回第i个元素的值*/
}

void display(Linklist L)  /*单链表元素输出函数*/
{
    
     Linklist p;
  p=L->next;
  while(p!=NULL)
   {
    
     printf("%4d",p->data);
     p=p->next;
    }
  printf("\n");
}
main()/*主函数*/
 {
    
    Linklist L=NULL; int i,x;
  L=creat(L);/*调用单链表建立函数*/
  printf("the Linklist is:\n");
  display(L); /*调用单链表元素输出(遍历)函数*/
  printf("please input the position  you want to insert:");/*请求输入插入操作位置*/
  scanf("%d",&i);
  printf("please input the node you want to insert:");/*请求输入需要插入的元素*/
  scanf("%d",&x);
  L=insert(L,i,x);/*调用单链表插入函数*/
  printf("the Linklist after inserted is:\n");
  display(L);/*调用单链表元素输出(遍历)函数*/
  printf("please input the node position you want to delete:"); /*请求输入删除操作位置*/
  scanf("%d",&i);
  L=delete(L,i); /*调用单链表删除函数*/
  printf("the Linklist after deleted is:\n");
  display(L); /*调用单链表元素输出(遍历)函数*/
  printf("please input the position you want to search:"); /*请求输入待查找元素的位置*/
  scanf("%d",&i);
  x=search(L,i);  /*调用单链表查找函数*/
  if (x)   /*如果查找成功,则显示第i个元素的值,否则显示第i个元素不存在*/
    printf("  the %dth elem is %d\n",i,x);
  else
    printf("  the %dth elem is not exsit\n");
}

4. Refer to Figure 2-1 for the running result:
Insert picture description here

Seven, design experiments

1. Experimental requirements

(1) Enter the length of the linked list and the value of each element, use the tail interpolation method to establish a two-way circular linked list, and output the value of each element in the linked list, and observe whether the input content is consistent with the output content.
(2) Insert an element with a value of x before the i-th element of the doubly circular linked list, and output the value of each element in the inserted linked list.
(3) Delete the i-th element in the doubly circular linked list, and output the value of each element in the deleted linked list.
(4) Find the value of the element x in the two-way circular linked list. If the search is successful, the position of the element in the linked list is displayed, otherwise it is displayed that the element does not exist.

2, Core algorithm tips

The storage structure used by the doubly circular linked list is described as follows:

 typedef struct DULNODE
       {
    
     Elemtype data;  /*数据域*/
         struct DULNODE *prior; /*指向前驱结点的指针域*/
         struct DULNODE  *next;/*指向后继结点的指针域*/
       }DULNODE,*DuLinklist;
      typedef int Elemtype;

Regardless of whether it is to establish a doubly circular linked list or insert, delete and find operations in a doubly circular linked list, the operation methods and steps are similar to those of a singly linked list. Just pay attention to two points:
(1) Wherever there is a modification chain in the operation, the two pointers of the predecessor and the successor must be modified.
(2) The judgment condition in the singly linked list operation algorithm: p==NULL or p!=NULL, in the operation algorithm of the circular linked list, it needs to be changed to: p!= L, where L is the head pointer of the linked list.

⑶ Description of core algorithm
void  DuList_creat (DuLinklist &L,int n) /*输入n个整数(其中n为表长),将这些整数作为data域并用尾插法建立一个带头结点的双向循环链表的函数*/
 {
    
       L=( DuLinklist)malloc(sizeof(DULNODE));/*为头结点分配空间*/
     L->next=L->prior=L;
/*使头结点的后继指针和前驱指针都指向自身,形成空的双向循环链表*/
     r=L;    /*尾指针初始指向头结点*/
for (i=0;i<n;i++)
       {
    
     p=(DuLinklist)malloc(sizeof(DULNODE));/*为一个新结点分配空间*/
         scanf("%d",&p->data); /*从键盘输入值,并保存在新结点数据域中*/
         p->next=r->next; /*新结点后继指针指向尾结点r的后继结点*/
         p->prior=r;    /*新结点的前驱指针指向尾结点r*/
  r->next=p;  /*尾结点的后继指针指向新结点*/
         r=p;      /*尾指针指向新结点,即新结点成为尾结点*/
}
L->prior=r;    /*使尾结点成为头结点的前驱结点*/
}
status DuList_search(DuLinklist L, int i;Elemtype &e)
  /*在带头结点的双向循环链表L中查找第i个元素,如果查找成功则用e返回其值*/
{
    
     p=L->next;  /*使指针p指向第1个元素结点*/
j=1;        /*计数器赋初值为1*/
  while (p!=L && j<i)  /*顺着后继指针查找第i个元素结点*/
   {
    
     p=p->next;
     j++;
}
if (j!=i)
    return ERROR;  /*如果i值不合法,即i值小于1或大于表长,则出错*/
e=p->data;    /*如果第i个元素存在,则将该元素值赋给e*/
return OK;
 }
status DuList_insert(DuLinklist &L,int i;Elemtype x) 
/*在带头结点的双向循环链表L中第i个位置之前插入新元素x*/
        {
    
       p=L->next;   j=1;
while(p!=L &&j<i) /*寻找插入位置,并使p指向插入位置的结点,即L中的第i个结点*/
            {
    
     p=p->next; 
 ++j;
}
      if(j!=i)
         return ERROR;  /*若位置不正确,即i小于1或大于表的长度加1,则出错*/
      s=(DuLinklist)malloc(sizeof(DULNODE)); /*为一个新结点s分配空间*/
      s->data=x;   /*为新结点数据域赋值*/
            /*下面四条语句就是完成修改链,将新结点s插入到p结点之前*/
      s->next=p;
p->prior->next=s;  
      s->prior=p->prior;
p->prior=s;  
      return OK;
}
status  DuList_delete(DuLinklist &L,int i,Elemtype &x)
/*在带头结点的双向循环链表L中,删除第i个元素结点,并用x返回其值*/
   {
    
      p=L->next;j=1;
     while(p!=L&&j<i) /*寻找被删结点,并使p指向被删结点的前驱*/
       {
    
     p=p->next; 
++j; 
}
     if (j!=i)
        return ERROR;   /*若位置不正确,即i小于1或大于表长,则出错*/
 q=p;   /*记下被删结点*/ 
 p->prior->next=p->next;   /*修改链使得p结点从链中脱离*/ 
 p->next->prior=p->prior;
 x=q->data;
 printf("the delete data is:%d\n",x);
 free(q);  //释放被删结点空间
return OK;
}

Reminder: Please compare the above algorithm with the corresponding operation algorithm on the singly linked list, pay special attention to the differences between them.
Insert picture description here

Guess you like

Origin blog.csdn.net/wkt1105436760/article/details/114240956