数据结构之线性表(建表-插入-删除-合并)

来源:互联网 发布:丑老太婆网络照片 编辑:程序博客网 时间:2024/05/17 05:55

这是我做过的GitHub小项目(知天气),入手安卓的朋友可以拿我的代码做参考哟,大家可怜可怜给个赞吧哈哈!https://github.com/Xxianglei/HeartWeather     

   首先先说下什么是线性表。线性表是最简单的一种数据结构。通俗的来讲,一个线性表就是以n个数据元素的有限序列(相当于数学中的“有限个元素的数列”)。当n=0时,线性表是空表。 
线性结构的特点: 
<1>:除第一个数据元素以外,每个数据元素都有前驱。 
<2>:除最后一个数据元素以外,每个数据元素都有后继。 
<3>:除以上两点外,每个数据元素都只有一个前驱和后继。
 
其次线性表的优缺点; 
优点:访问某个位置的数据元素比较方便。 
缺点:数据元素的插入和删除比较麻烦。时间复杂度也比较高。 
现在来看一下怎么实现的。 
先了解下其中的宏定义,以后的数据结构中也会用到同样的名称。

#define TRUE   1  #define FALSE   0  #define OK    1  #define ERROR   0  #define INFEASIBLE -1  #define OVERFLOW -2  typedef int Status;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

好了,现在才刚刚开始。 
以下代码都是用C语言实现的。 
首先是—–线性表的动态分配顺序存储结构——-

#define LIST_INIT_SIZE 100 //线性表初始空间分配量  #define LISTINCREMENT   10 //线性表空间分配的增量 typedef int ElemType; //这里用整型数据类型代替其他数据类型typedef struct LNode{      ElemType  *elem;        //存储空间的基地址      int      lenght;        //当前的长度      int      listsize;      //当前分配的存储容量  }SqList;   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

接下来是创建一个空的线性表:

//构造空的线性表  InitList(La)的具体实现)Status Listinit(SqList &L){       L.elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));      if(!L.elem) exit(OVERFLOW);  //分配存储空间失败      L.lenght = 0;                //初始空表长度为0      L.listsize = LIST_INIT_SIZE  ;//初始存储容量为100      return OK;  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

然后是对顺序线性表的插入进行的操作:

//对顺序线性表的插入进行的操作:Status ListInsert(SqList &L, ElemType e, int i)  // 参数为: 操作的表  传出的删除值  删除位置(不是数据下标){      ElemType *p,  *q;      if(i<1 ||i > L.lenght+1) return ERROR;  //i值不合法      if (L.lenght >= L.listsize)     {          ElemType *newbase = (ElemType *)realloc(L.elem ,(L.listsize +LISTINCREMENT)*sizeof(ElemType));          if(!newbase) return OVERFLOW;   //存储分配失败            L.elem = newbase;               //新基值          L.listsize += LISTINCREMENT;    //增加存储容量      }      q = &L.elem[i-1];                     //q为插入的位置  比如传入2指的是第二个数  实际是下标是1     for (p = &L.elem[L.lenght-1]; p>=q; --p)     {          *(p+1)=*p;               //i元素之后的元素往后移动      }      *q = e;                             //插入e      L.lenght +=1;                       //表长加一    return OK;  }   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

删除操作也很简单直接上代码

//线性表的删除操作: Status ListDelete(SqList &L, int i, ElemType &e){      int *p,  *q;      if(i<1 ||i > L.lenght) return ERROR;  //i值不合法 ,超过了线性表的长度或者在第一个元素前面当然就是不合法了。    q = &L.elem[i-1];                    //被删除元素的位置为i,i从0开始的所以是i-1;    e = *q;                               //被删除元素的值赋值给e      for (p = q; p< (L.elem + L.lenght-1);p++)    { //元素左移          *(p)=*(p+1);    }      L.lenght--;  //表长减一    return OK;  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

合并两个线性表

//合并两个线性表 void mergeList(SqList La, SqList Lb,  SqList &Lc){      int *pa, *pb, *pc;       Listinit(Lc);          //初始化Lc     // Lc.lenght = Lc.listsize;      Lc.listsize=Lc.lenght=La.lenght + Lb.lenght;        pc = Lc.elem=(ElemType*)malloc(Lc.listsize*sizeof(ElemType));      if(!pc)exit(OVERFLOW);  // 维持健壮性的判断    pa = La.elem;      pb = Lb.elem;      while (pa <= &La.elem[La.lenght -1] && pb <= &Lb.elem[Lb.lenght -1])    {          if (*pa <= *pb) *pc++ = *pa++;          else *pc++ = *pb++;      }      while(pa <= &La.elem[La.lenght -1]) *pc++ = *pa++; //插入La的剩余元素      while(pb <= &Lb.elem[Lb.lenght -1]) *pc++ = *pb++; //插入Lb的剩余元素  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

完整的代码,仅供参考:

#include <stdio.h>  #include<stdlib.h>//宏定义  #define TRUE   1  #define FALSE   0  #define OK    1  #define ERROR   0  #define INFEASIBLE -1  #define OVERFLOW -2   #define LT(a,b)   ((a)<(b))  #define N = 100         #define LIST_INIT_SIZE 100 //线性表初始空间分配量  #define LISTINCREMENT   10 //线性表空间分配的增量  typedef int Status;  typedef int ElemType;  typedef struct LNode{      ElemType  *elem;        //存储空间的基地址      int      lenght;        //当前的长度      int      listsize;      //当前分配的存储容量  }SqList;  //构造空的线性表 Status Listinit(SqList &L){       L.elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));      if(!L.elem) exit(OVERFLOW);  //分配存储空间失败      L.lenght = 0;                //初始空表长度为0      L.listsize = LIST_INIT_SIZE  ;//初始存储容量为100      return OK;  }  //对顺序线性表的插入进行的操作:Status ListInsert(SqList &L, ElemType e, int i){      ElemType *p,  *q;      if(i<1 ||i > L.lenght+1) return ERROR;  //i值不合法      if (L.lenght >= L.listsize)     {          ElemType *newbase = (ElemType *)realloc(L.elem ,(L.listsize +LISTINCREMENT)*sizeof(ElemType));          if(!newbase) return OVERFLOW;   //存储分配失败            L.elem = newbase;               //新基值          L.listsize += LISTINCREMENT;    //增加存储容量      }      q = &L.elem[i-1];                     //q为插入的位置  传入2  实际是1     for (p = &L.elem[L.lenght-1]; p>=q; --p)     {          *(p+1)=*p;               //i元素之后的元素往后移动      }      *q = e;                             //插入e      L.lenght +=1;      return OK;  }  //线性表的删除操作: Status ListDelete(SqList &L, int i, ElemType &e){      int *p,  *q;  //Status相当于int还是不太习惯写。    if(i<1 ||i > L.lenght) return ERROR;  //i值不合法 ,超过了线性表的长度或者在第一个元素前面当然就是不合法了。    q = &L.elem[i-1];                     //被删除元素的位置为i,i从0开始的所以是i-1;    e = *q;                               //被删除元素的值赋值给e      for (p = q; p< (L.elem + L.lenght-1);p++)    { //元素左移          *(p)=*(p+1);    }      L.lenght--;    return OK;  }  //合并两个线性表 void mergeList(SqList La, SqList Lb,  SqList &Lc){      int *pa, *pb, *pc;       Listinit(Lc);          //初始化LC\pc = Lc.elem;     // Lc.lenght = Lc.listsize;      Lc.listsize=Lc.lenght=La.lenght + Lb.lenght;        pc = Lc.elem=(ElemType*)malloc(Lc.listsize*sizeof(ElemType));      if(!pc)exit(OVERFLOW);    pa = La.elem;      pb = Lb.elem;      while (pa <= &La.elem[La.lenght -1] && pb <= &Lb.elem[Lb.lenght -1])    {          if (*pa <= *pb) *pc++ = *pa++;          else *pc++ = *pb++;      }      while(pa <= &La.elem[La.lenght -1]) *pc++ = *pa++; //插入La的剩余元素      while(pb <= &Lb.elem[Lb.lenght -1]) *pc++ = *pb++; //插入Lb的剩余元素  }  int main(){    SqList  La,Lb,Lc;      ElemType e;      int init,i;      Listinit(La);      printf("输入数据量为10的表:\n") ;    for(int i=0;i<10;i++)//事例先输入10个数,大小可以自己更改     {        scanf("%d",&La.elem[La.lenght++]);    }     printf("\n\n");    ListInsert(La,10,2);  //在第2个位置插入一个数据元素     printf("插入数据后表结构为:\n\n");    for(int i=0;i<La.lenght;i++)    {        printf("%d ",La.elem[i]);//输出插入后的顺序线性表     }    printf("\n");     int m;//被删除的元素赋给m     ListDelete(La,2,m);     printf("\n值为%d的元素已经被删除!\n\n",m);    for(int i=0;i<La.lenght;i++)    {        printf("%d ",La.elem[i]);    }    printf("\n\n");    Listinit(Lb);  //初始化lb表(空) printf("---------------------------");printf("\n输入另一组数据量为10的表:\n\n") ;     for(int i=0;i<10;i++)//输入另一个顺序线性表     {        scanf("%d",&Lb.elem[Lb.lenght++]);    }     /*for(int i=0;i<Lb.lenght;i++)    {        printf("%d ",Lb.elem[i]);//输出另一个顺序线性表     }    printf("\n");*/     mergeList(La,Lb,Lc);//合并两个线性表     for(int i=0;i<Lc.lenght;i++) //输出两个线性表     {        printf("%d ",Lc.elem[i]);    }        return 0;}
阅读全文
1 0
原创粉丝点击