数据结构——线性表

头指针或者尾指针需要改变,并且需要把改变的值带回到主程序,带回到调用处需要用到指针的指针;
当尾指针不发生改变,或者即使发生了改变也不希望带回到主程序当中就用指针;

1 线性表的定义

  线性表的元素是有限的,元素之间有顺序的一个挨着一个

  数学定义:

    将线性表标记为以序列:

    a1,a2,a3,...,ai-1,ai,ai+1,...,an

    序列中ai-1位于ai的前面,称ai-1是ai的直接前驱;

    序列中ai+1位于ai的后面,称ai+1是ai的直接后继;

    a1仅有直接后继,an仅有直接前驱;

2 线性表的抽象数据类型

  ADT线性表(Abstract Data Type抽象数据类型)

  data

    a1,a2,a3,...,ai-1,ai,ai+1,...,an

  operation

    InitList(L)         初始化操作建立一个空的线性表

    ListEmpty(L)        若线性表为空,返回true

                        若线性表不为空,返回false

    ClearList(L)        将线性表中的所有元素删除

    GetElement(L,i)     返回线性表L中下标为i的元素

    LocateElement(L,e)  在线性表L中查找指定元素e

                        若查找成功,返回e在L的下标中

                        若不成功,返回-1

    InsertInit(L,i,e)   在线性表L中下标为i的位置插入元素e

    DeleteList(L,i)     将线性表L中下标为i的元素删除

    ListLength(L)       返回线性表L中元素的个数;线性表的长度就是表中保存的数据元素的个数

  endADT

3 顺序存储结构

  用一段地址连续的存储空间,依次存储线性表中的数据元素(数组可以实现连续存储)

  示意图:

a1
a2
...
ai-1
ai
ai+1
...
an

4 线性表的顺序表存储结构

    #define LISTSIZE 100

    typedef int DataType;

    typedef struct SeqList    //typedef作用给结构体起了一个别名叫SeqList,红色部分作用相当于int

    {                         //给结构体起别名是为了后面调用结构体的时候不用敲struct,否则调用时要struct SeqList

      DataType data[LISTSIZE];  

      int nLength;    //线性表元素个数

    }SeqList;     

  数据长度:线性表中能保存的数据元素最多个数,是一个固定值

  线性表长度:线性表中已经保存的数据元素个数,是一个随时变化的值

  地址计算:

  地址(address):存储器中每个存储单元的编号

    address(ai)=address(ai-1)+n

               =address(a0)+n*(i-1)

    n:每个元素所占的字节

  下标(subscript):数组中每个元素的编号

  

4.1 初始化操作

void InitList(SeqList *list)
{
  list->nLength=0;
}

  

    sl是一个线性列表,程序运行时会给sl分配一个存储空间,当调用函数initList后,相当于指针变量list保存了sl的地址,占4个字节。

  

4.2 判断表是否为空

void ListEmpty(SeqList *list)
{
  return list->nLength==0;
}

 

4.3 将线性表中的所有元素删除

void clearList(SeqList *list)
{
  list->nLength=0;
}

4.4 获取线性表L中元素个数

int listLength(SeqList *list)
{
  return list->nLength;
}

4.5 获取线性表中下标为i的元素

#define LISTSIZE 100
typedef int DataType;
typedef struct SeqList
{
  DataType data[LISTSIZE];
  int nLength;
}SeqList;
DataType *getNode(SeqList *list,int i)
{
  if(i<0 || i>list->nLength-1)
    return NULL;   //NULL代表没有数据存在
  return &list->data[i];
}

4.6 在线性表中查找指定元素

int LocateNode(SeqList *list,DataType x)
{
  for(int i=0;i<list->nLength;i++)
    if(list->data[i]==x)
      return i;
  return -1
}

4.7 在线性表中下标为i的位置插入元素

#define LISTSIZE 100
typedef int DataType;
typedef struct SeqList
{
  DataType data[LISTSIZE];
  int nLength;
}SeqList;

bool insert(SeqList *list,int i ,DataType x)
{
  if(list->nLength==LISTSIZE)
    return flase;
  int insertPositon=i;
  if(i<0)
    insertPositon=0;
  if(i>list->nLength-1)
    insertPositon=list->nLength;
  for(int j=list->nLength-1;j>=insertPositon;j--)
    list->data[j+1]=list->data[j];
  list->data[insertPositon]=x;
  list->nLength++;
  return true;
}

void main()
{
  SeqList sl;
  ...
  insert(&sl,5,10); //在第五个位置插入元素10
}

4.8 删除线性表中下标为i的元素

#define LISTSIZE 100
typedef int DataType;
typedef struct SeqList
{
  DataType data[LISTSIZE];
  int nLength;
}SeqList;

bool deleList(SeqList *list,int i)
{
  if(i<0 || i>=list->nLength)
    return false;
  for(int j=i;j<list->nLength;j++)
    list->data[j]=list->data[j+1];
  list->nLength--;
  return true;
}

void main()
{
  SeqList sl;
  ...
  deleList(&sl,3);  //删除下标为3的元素
}

4.9 将两个线性表合并

void union(SeqList *a,SeqList *b)
{
  if(a->nLength + b->nLength >LISTSIZE)
    return;
  for(int i=0;i<b->nLength;i++)
  {
    DataType e=b->data[i];
    if(locadeNode(a,e)==-1)   //在线性表中查找指定元素
      insert(a,a->nLength,e); //在线性表中下标为i的位置插入元素
  }
}

4.10 将线性表倒置

void reverse(SeqList *list)
{
  for(int i=0;i<list->nLength/2;i++)
  {
    DataType t=list->data[i];
    list->data[i]=list->data[list->nLength-1-i];
    list->data[list->nLength-1-i]=t;
  }
}

4.11 线性表遍历

void print(DataType d)
{
  printf("%d\n",d);
}

void trave(SeqList *list,void(visitFun)(DataType))
{
  for(int i=0;i<list->nLength;i++)
  {
     visitFun(list->data[i]);
  }
}

void main()
{
  SeqList sl;
  ...
  trave(&sl,print);
}
posted @ 2018-12-20 18:57  dongry  阅读(501)  评论(0编辑  收藏  举报