• 线性表的链式存储实现(不带头结点)


    建议使用带头结点的版本,因为不带头结点的版本有一些缺陷:

    在插入或删除操作中,如果返回类型不是链表,那么形参类型一定是指向头结点的指针(也就是二级指针),因为传递指针实参时,形参实际上是实参的副本,所以实参的指向是一直不变的,如果在插入过程中插在了头指针的下一个位置(也就是第一个结点的位置),如果返回类型不是链表或形参不是二级指针,那么插入操作对原链表时无效的,而如果删除释放了第一个结点,那么由于实参的指向始终是第一个结点的那块内存,那么实参指针就是指向一块不知名的内存,成为野指针。总的来说,不带头结点的版本,在删除或插入操作中,如果返回类型不是链表或形参不是二级指针,那么该操作不能作用在第一个结点上

    关于指针作为形参的问题可以参考:https://www.cnblogs.com/hi3254014978/p/9478307.html

    LinkList.h

     1 #ifndef LINKLIST_H_INCLUDE
     2 #define LINKLIST_H_INCLUDE
     3 
     4 #include <stdio.h>
     5 #include <stdlib.h>
     6 #include <stdbool.h>
     7 
     8 #define ERROR -1
     9 
    10 typedef int ElementType;
    11 
    12 typedef struct LNode* PtrToNode;
    13 struct LNode{
    14     ElementType Data;
    15     PtrToNode Next;
    16 };
    17 
    18 typedef PtrToNode Position;        //这里的位置某个结点的结点指针
    19 typedef PtrToNode List;
    20 
    21 List L;
    22 
    23 //链表长度
    24 int Length(List L);
    25 
    26 //根据位序查找元素
    27 ElementType FindKth(List L, int K);
    28 
    29 //根据元素查找相应的结点
    30 Position Find(List L, ElementType X);
    31 
    32 //在指定位置之后插入元素
    33 List Insert(List L, ElementType X, int i);
    34 
    35 bool Delete(List *L, int i);
    36 
    37 void printList(List L);
    38 
    39 
    40 
    41 
    42 #endif

    LinkList.c

      1 #include "LinkList.h"
      2 
      3 int Length(List L)
      4 {
      5     int cnt = 0;
      6     List p = L;        //当前p指向第一个结点
      7     while (p)
      8     {
      9         cnt++;
     10         p = p->Next;
     11     
     12     }
     13     return cnt;
     14 
     15 }
     16 
     17 ElementType FindKth(List L, int K)
     18 {
     19     Position p = L;
     20     int cnt = 1;
     21     while (p && cnt < K)
     22     {
     23         p = p->Next;
     24         cnt++;
     25     }
     26     if ((cnt == K) && p)
     27         return p->Data;
     28     else
     29         return ERROR;
     30 }
     31 
     32 Position Find(List L, ElementType X)
     33 {
     34     Position p = L;
     35     while (p && p->Data != X)
     36         p = p->Next;
     37     if (p)
     38         return p;
     39     else
     40         return NULL;
     41 }
     42 
     43 List Insert(List L, ElementType X, int i)
     44 {
     45     Position tmp, pre;
     46     tmp = (Position)malloc(sizeof(struct LNode));
     47     if (i == 1)
     48     {
     49         tmp->Data = X;
     50         tmp->Next = L;
     51         return tmp;
     52     }
     53 
     54     else
     55     {
     56         int cnt = 1;
     57         pre = L;
     58         while (pre && cnt < i - 1)
     59         {
     60             pre = pre->Next;
     61             cnt++;
     62         }
     63         if (pre == NULL || cnt != i - 1)        //如果所招结点不再L中
     64         {
     65             printf("Insert position parameter error!
    ");
     66             free(tmp);
     67             return L;
     68         }
     69         else
     70         {
     71             tmp->Data = X;
     72             tmp->Next = pre->Next;
     73             pre->Next = tmp;
     74             return L;
     75         }
     76     }
     77 }
     78 
     79 bool Delete(List *L, int i)
     80 {
     81     Position tmp, pre;
     82     int cnt = 1;
     83     pre = *L;
     84     if (i == 1 && pre)
     85     {
     86         *L = (*L)->Next;        //如果这里没有传*L,而是L,那么这里的L只是实参的副本,
     87                                 //所以如果删除并释放第一个结点后,因为实参的L还是指向第一个结点的,所以第一个结点被释放后,
     88                                 //实参L会只想一块不知名的内存,成为野指针,所以建议使用带头结点的链表
     89         free(pre);
     90         return true;
     91     }
     92     else
     93     {
     94         while (pre && cnt < i - 1)
     95         {
     96             pre = pre->Next;
     97             cnt++;
     98         }
     99         if (pre == NULL || cnt != i - 1 || pre->Next == NULL)        //i出错或链表为空
    100         {
    101             printf("Delete position parameter error!
    ");
    102             return false;
    103         }
    104         else
    105         {
    106             tmp = pre->Next;
    107             pre->Next = tmp->Next;
    108             free(tmp);
    109             return true;
    110         }
    111     }
    112     
    113 }
    114 
    115 void printList(List L)
    116 {
    117     Position p;
    118     p = L;
    119     while (p)
    120     {
    121         printf("%d ", p->Data);
    122         p = p->Next;
    123     }
    124     printf("
    ");
    125     return ;
    126 }
  • 相关阅读:
    Java转大数据开发全套视频资料
    Java注解Annotation的用法
    SpringBoot集成CAS单点登录,SSO单点登录,CAS单点登录(视频资料分享篇)
    零基础如何学习Java和web前端
    如何看待B站疑似源码泄漏的问题?
    如何自学编程,零基础适合学习Java或者Web前端吗,非科班的能学java吗?
    Spring中常用的注解,你知道几个呢?
    学习分布式系统需要怎样的知识?
    程序员如何学习互联网前言技术呢,我给你10个建议
    回看面试中的这些坑,你踩过几个?
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/9723768.html
Copyright © 2020-2023  润新知