zoukankan      html  css  js  c++  java
  • 数据结构01 顺序表、链表实现

    概述


    这学期初学数据结构,同时学C语言。由于修的二专,没什么伙伴可以一块讨论。困惑还是很多的,希望自己可以坚持下来吧。

    刚开始学的是线性表。线性表又可以分为顺序表和链表,两者的区别在于存储结构不同。

    顺序表的存储特点是 依次存储,地址连续。因为地址连续,所以可以随机存取。

    写一个构造体,命名为SqList。

    typedef struct
    {
      int data[Max_Length];
      int length;
    }SqList;

    而链表的特点是 任意存放,存储单元可以是不连续的,通过指针将一个个元素连接起来。指针是个神奇的东西。。

    写一个链表构造体,命名为Linknode。

    typedef struct node
    {
        int data;
        struct node *next;
    }Lnode,*Linklist;

    显然,两者各有优点和缺点。优缺点互补。

    顺序表插入和删除


     顺序表的缺点是插入删除繁琐,导致这一致命问题的原因在于依次存放,如果想插入一个元素,那势必要将表中该位置以后的元素后移一位。如果想删除一个元素,势必要将表中该位置以后的元素前移一位

    int List_Insert(SqList &L,int i,int e)
    {
      int *p;
      int *q;
      //插入位置的前一位置
      q = &(L.data[i - 1]);
      //插入位置的后面的元素后移一位
      for(p = &L.data[L.length - 1];p >= q;--p)
      {
        *(p + 1) = *p;
      }
      *q = e;
      ++L.length;
      return 0;
    }
    //按元素删除
    int List_Delete_Elem(SqList &L,ElemType e)
    {
      int j;
      //找到第一个所给元素
      for (j = 0;j <= L.length - 1;j++)
      {
        if(L.data[j] == e) break;
      }
      if (j >= L.length)
      {
        return 0;
      }
      int *p = &(L.data[j]);
      int *q = &L.data[0] + L.length -1;
      //删除元素的后面元素前移
      for (++p;p <= q;++p)
        {
          *(p - 1) = *p;
        }
      --L.length;
      return 1;
    }
    
    // 按照位置,删除表中指定位置元素
    Status List_Delete_Pos(SqList &L, int i)
    {
      if (i < 1 || i > L.length)
      {
        return 0;
      }
      int *p = &(L.data[i-1]);
      int *q = &L.data[0] + L.length -1;
      for (++p; p <= q; ++p)
        {
          *(p - 1) = *p;
        }
      --L.length;
      return 1;
    }

     依次存储 的问题在于,元素之间相互影响,这就好比一支军队,排列整齐的一列队伍,一个人的变动会影响全局。

    那么,如果不是依次存储呢?

    链表的插入和删除


    链表的优势在于任意存储,形状不固定。人们将它视为一个链条,相互之间的连接依靠指针。我们老师的比喻比较形象,指针是开锁的钥匙,锁在另一个位置。一个元素包括下一个元素的地址,因此我们进入这个元素的房间,便可以找到这个房间存放的另一个房间的地址,从而也就找到了下一个房间。这里,一个房间由两种基本类型组成,一个是数据,一个是指针。

    那么,链表如何插入和删除元素呢?我们想加入一个元素P,那个先找到加入的位置的前一个元素A,先使得P存放的地址是A存放的地址,然后使得A存放的地址是P的地址。同理,删除一个元素P,先找到加入的位置的前一个元素A,使得A存放的地址是P的存放的地址。

    int List_Insert(Linklist &L,int i,int e)
    {
        Linklist p,s;
        p = L;
        int j = 0;
        while(p->next && j < i - 1)
        {
            p = p ->next;
            ++j;
        }
        if(!p || j > i - 1) return ERROR;
        s = (Linklist)malloc(sizeof(Lnode));
        s->data = e;
        s->next = p->next;
        p->next = s;
        return 1;
    }
    
    int List_Delete_Pos(Linklist &L,int i)
    {
        Linklist p,q;
        p = L;
        int j,e ;
        j = 0;
        while(p->next && j < i - 1)
        {
            p = p->next;
            j++;
        }
        if(!(p->next) || j > i - 1) return ERROR;
        q = p->next;
        p->next = q->next;
        e = q->data;
        free(q);
        return 1;
    }
    
    int List_Delete_Elem(Linklist &L,int m)
    {
        Linklist p,q;
        p = L;
        int j,e ;
        j = 0;
        while(p->next && p->next->data != m)
        {
            p = p->next;
        }
        if(!(p->next)) return ERROR;
        q = p->next;
        p->next = q->next;
        e = q->data;
        free(q);
        return 1;
    } 
    小钻风,大三狗。 金融和计算机。
  • 相关阅读:
    ASP.Net 反射显示
    ASP.Net 反射简单工厂模式
    ASP.Net MVC生成验证码
    ASP.Net EF架构
    ASP.Net 邮箱发送
    ASP.Net 反射简单
    ASP.Net 显示
    新年快乐
    测试开发比
    Linkbot介绍
  • 原文地址:https://www.cnblogs.com/jiawei666/p/7701434.html
Copyright © 2011-2022 走看看