zoukankan      html  css  js  c++  java
  • 链表的各种操作

        链表的操作包括插入、删除、翻转、清空、判空、求链表长度等,下面分别找了链表的插入和删除操作的图,第一个是插入,第二个是删除。

        

          在插入的时候,要先找到待插入的位置,一般是找到待插入位置的前一个位置,假如要在3号位置插入,那就找到2号位置,这样方便插入,下面

    的代码中就提到了这一点,然后把新结点插入在3号位置就行了;有没有发现在链表中插入某一结点和用头插法创建链表有点像 !

         在删除的时候,还是要先找到要删除的位置,基本上和插入操作一样,也是找到待删除位置的前一个位置,上面图中要删除A3,就找到A2,改变

    A2的next,跳过A3直接指向A4,这样链表中就没了A3。

       关于链表的具体用法,还是看下面代码吧,代码我写的超详细,也测试过了,基本上包括了链表的各种操作,耐心点看吧!如有不对的地方,欢迎指出!

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #define N  10     //结点个数
      4 typedef struct LNode
      5 {
      6     int data;
      7     struct LNode *next;
      8 }LNode,*LinkList;
      9 
     10 LinkList creat_Linklist()  //已知节点个数,并且不带头结点
     11 {
     12      LNode   *head=NULL,*s,*rear=NULL;  //尾插法需要用到尾指针,rear是尾指针
     13      for(int i=1;i<=N;i++)
     14      {
     15          s=(LinkList)malloc(sizeof( LNode));
     16          scanf("%d",&s->data);
     17          s->next=NULL;    //把当前结点next置空NULL
     18          if(i==1)    //用来标记插入的节点是否为第一个节点,是的话就让头结点head指向第一个节点
     19              head=s;
     20          else    
     21              rear->next=s;   //不是头结点的话就让上一个节点的next指向当前结点
     22          rear=s;   //尾指针rear指向当前节点
     23      }
     24      return head;   //返回头指针
     25 }
     26 int LinkList_length(LinkList head)  //q求链表长度
     27 {
     28  
     29     int count=0;
     30     LNode * p=NULL;
     31     p=head;
     32     while(p!=NULL)
     33     {
     34          p=p->next;
     35          count++;
     36     }
     37     return count;
     38 }
     39 LinkList Clear_LinkList(LinkList head)  //用于清空没有头结点的链表,只是清空,没有释放掉,直接把头指针置空NULL即可
     40 {  
     41          if(head==NULL) 
     42          {
     43              printf("链表为空
     ");
     44              exit(-1);     
     45          }
     46          return NULL;  
     47 }  
     48 int EmptyList(LinkList head)//用于判断没有头结点的情况;空表返回1,非空返回0
     49 {
     50        if(head==NULL)
     51             return 1;
     52        else
     53             return 0;
     54 }
     55 LinkList Search(LinkList head,int x)  //查找链表中的某一数据,查找成功返回一个指向它的指针,失败返回NULL
     56 {
     57          LNode *p;
     58          p=head;
     59          while(p)
     60          {      
     61             if(p->data!= x)
     62                p=p->next;
     63             else
     64                break;
     65          }
     66          return p;
     67 }
     68 void Print_LinkList(LinkList head)  //打印链表
     69 {
     70          LNode *p;
     71          p=head;
     72          while(p!= NULL)
     73          {          
     74               printf("%d ",p->data);  
     75               p=p->next;
     76          }
     77 }
     78 LinkList reverseList(LinkList head)  //翻转链表
     79 {
     80             LNode *pre,*cur,*net;
     81             pre=head;
     82             cur=pre->next;
     83             while(cur!= NULL)  //当前指针cur非空
     84             {
     85                  net=cur->next;
     86                  cur->next=pre;
     87                  pre=cur;
     88                  cur=net;
     89             }
     90             head->next=NULL;  //将原来链表中第一个结点的next置空NULL
     91             head=pre;  //此时pre指向最后一个结点
     92             return  head;
     93 }
     94 LinkList DeleteList(LinkList head,int i) //删除序号为i的结点,结点序号从1开始
     95 {
     96          int j=1;
     97          LNode *p,*q;
     98          p=head;
     99          while(p->next!=NULL&&j<i-1)
    100          {
    101                p=p->next; 
    102                j++;      //查找待删除结点的前一个节点
    103          }
    104          if ( !(p->next) || j>i-1) //1号位置无法删除
    105          {
    106              printf("删除位置错误");
    107              return  0;
    108          }
    109          q=p->next;  //q指向待删除结点
    110          p->next=q->next;  //跳过待删除结点,
    111          free(q);    //释放待删除结点
    112          return  head;
    113 }
    114 LinkList InsertList(LinkList head,int i,int e)//在序号为i的结点位置插入e
    115 {    
    116          int j=1;
    117          LNode *p,*q;
    118          p=head;
    119          while(p&&j<i-1) //查找待插入位置的前一个位置
    120          {
    121                p=p->next;
    122                j++;
    123          }
    124          if(!p || j>i-1) //1号位置无法插入
    125          {
    126              printf("插入位置错误");
    127              return  0;
    128          }
    129          q=(LinkList)malloc(sizeof(LNode)); //为新结点开辟空间
    130          q->data=e;
    131          q->next=p->next;
    132          p->next=q;
    133          return  head;
    134 }
    135 int main()
    136 {
    137     LinkList p;
    138     p=creat_Linklist();
    139     printf("链表中的数据为:");
    140     Print_LinkList (p);
    141     printf("
    链表长度:%d
    ",LinkList_length(p));
    142     printf("翻转后的链表为:");
    143     p=reverseList (p);   //翻转链表,返回头指针
    144     Print_LinkList (p);
    145     printf("
    删除序号为3的结点后,链表中的元素为:");
    146     p=DeleteList(p,3);   //删除序号为3的结点,序号从1开始
    147     Print_LinkList(p);
    148     printf("
    删除序号为3的结点后,链表长度:%d",LinkList_length(p));
    149     printf("
    在序号为3的结点位置插入80后,链表中的元素为:");
    150     p=InsertList(p,3,80);
    151     Print_LinkList(p);
    152     printf("
    在序号为3的结点位置插入80后,链表长度为:%d
    ",LinkList_length(p));
    153     LinkList s;
    154     s=Search(p,80);//在链表里查找某一数据
    155     if(s==NULL)
    156         printf("在链表查找失败
    ");
    157     else
    158         printf("在链表查找成功,结果为:%d
    ",*s);
    159     printf("结果为1表示链表为空,为0表示链表非空:%d
    ",EmptyList(p));
    160     p=Clear_LinkList(p); //清空链表
    161     printf("结果为1表示链表为空,为0表示链表非空:%d
    ",EmptyList(p));
    162     printf("清空链表后,链表长度为:%d
    ",LinkList_length(p));
    163     return 0;
    164}

    调试了好久,结果如下:

    另外链表的销毁操作我没测试,附上代码,有兴趣的自己去测试吧

     1 void  Destroy_LinkList (LinkList  head)
     2 {
     3          LNode *p,*q;
     4          p=head;
     5          while(p  != NULL)
     6          {    q=p;
     7                p=p->next;
     8                free(q);
     9          }
    10 }

    转载请注明出处  !

    2020-04-28      23:07:21

  • 相关阅读:
    如何理解和计算活跃度。做了张脑图。欢迎大家提意见
    在虚拟服务器调试castle项目
    生成缩略图
    自己写的分页函数
    asp.net2.0 自带的邮件发送
    在.NET下如何用WebService实现身份认证,及如何跟踪用户的访问,如类似Possport的功能,不会还是用Session吧?
    邮箱验证
    ASP.NET菜鸟之路之Request小例子
    ASP.NET菜鸟之路之Seesion小例子
    ASP.NET菜鸟之路之Response小例子
  • 原文地址:https://www.cnblogs.com/buanxu/p/12796127.html
Copyright © 2011-2022 走看看