zoukankan      html  css  js  c++  java
  • 线性表的链式存储实现(不带头结点)

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

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

    关于指针作为形参的问题可以参考: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 }
  • 相关阅读:
    poj 1088 滑雪
    位运算与bitset
    hdu 4607 Park Visit
    树的直径
    codeforces 495D Sonya and Matrix
    German Collegiate Programming Contest 2015(第三场)
    BAPC 2014 Preliminary(第一场)
    Benelux Algorithm Programming Contest 2014 Final(第二场)
    E. Reachability from the Capital(tarjan+dfs)
    poj2104 K-th Number(划分树)
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/9723768.html
Copyright © 2011-2022 走看看