手记

【学习笔记】数据结构——线性表

最近在看数据结构,来写点笔记~~~
先看基本定义
线性表:由同类型数据元素构成有序序列的线性结,是最基本、最简单、也是最常用的一种数据结构。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。其中;
表中元素个数称为线性表的长度,
当线性表没有元素时,称为空表,表的起始位置称为表头,表的结束位置称为表尾。

我们再来看一些基本操作的实现:

先定义一个结构体

typedef struct{
    Element Type Data[MAXSIZE];
    int Last; 
}List;
List L,*PtrL;    
定义这个结构体可以实现简单的操作:
L.Data[i]或PtrL->Data[i] //访问下标为i的元素
L.Last+1或PtrL->Last+1 //可以表示线性表的长度                                                        

//1.初始化线性表


List *MakeEmpty(){
    List *PtrL;
    PtrL = (List *)malloc( sizeof(List) );//向系统请求List长度个内存空间
    PtrL -> Last = -1;//下标为0就是有一个元素了,所以-1就代表没有元素,即数组为空。
    return PtrL;
}

2.查找操作

//查找X
int Find(ElementType, List *PtrL){
    int i=0;//准备开始
    while(i<=PtrL->Last  &&PtrL->Data[i]!=X)//如果i在线性表范围内并且不等于X时,则+1
    i++;
    if (i >PtrL->Last )  return -1;   //i一直加当它超出范围时,返回-1
    else    return i;//找到则返回i。
}

3.插入操作:把握一个关键就是插入的时候需要把某点以后的所有元素依次后移。

void Insert (ElementType X, int i, List *PtrL){
    int j;
    if( PtrL->Last==MAXSIZE-1){     //如果表满了的话则不能插入
    printf( "表满 " );
    return;
    }  
    if( i<1  ||  i > PtrL->Last+2){   //判断位置。
    printf(" 位置不合法 ");
    return;
  }
    for(  j=PtrL->Last;  j>=i-1; j--)
         PtrL->Data[ j+1 ] = PtrL->Data[j];//前一位向后移动
 PtrL->Data[i-1]=X;                   //插入新元素
 PtrL->Last++;        //Last指向最后一个元素
 return;
}

4.删除操作

void Delete( int i ,List *PtrL){
   int  j;
   if( i <1 || i>PtrL->Last+1){   //查无此数的条件
    printf("不存在第%d个元素");
    return ;
    }
    for ( j = 1; j <= PtrL -> Last; j++ )
    PtrL ->Data[j-1] =PtrL -> Data[j];  //直接将后面的数向前移,要删除的数就被覆盖了
    PtrL->Last--;     //因为少了一个数 Last要减一
    return;
}

  如我们所见线性表的插入、删除操作需要移动大量元素,效率低而且表的长度难以确定,接下来我们看另一种存储结构——链式存储。

  链式存储不要求逻辑上相邻的两个元素物理上也相邻;插入、删除不需要移动数据元素,只需要修改“链”。也就是说,表中的数据不需要一个挨着一个排列,这就没有上面顺序存储结构中删除和插入时将所有数据移动的问题,这样会更有效率~~~
我们来看看基本操作~

先定义结构体

typedef struct Node{
    ElementType Data;
    struct Node *Next;
}List;
List L, *PtrL;

1.求表长

int Length ( List *PtrL){
    List *p = PtrL;   //p指针指向表中第一个结点
    int j=0;
    while ( p ){ 
       p = p->Next;   //当p不为空时,指向下一个结点然后j++,从而算出表长
       j++;
   }
    return  j;
}

2.链表查找
(1)按序号查找

List *FindKth( int K, List *PtrL){
  List *p = PtrL;   // //p指针指向表中第一个结点
  int i = 1;
  while ( p != NULL && i<K ){  //判断是否在合法范围内
    p=p->Next;
    i++;
  }
  if ( i == K) return p;  //找到了第K个元素,返回指针;
  else return NULL;  //查找失败,返回空。
}

(2) 按值查找

List *Find ( ElementType X,List *PtrL){
    List *p = PtrL;
    while ( p != NULL && p->Data != X )
    p = p->Next;
 return p; 
}

3.插入操作

List *Insert ( ElementType X, int i, List *PtrL ){
   List *p, *s;
   if( i == 1){          //插入表头
    s = (List *)malloc(sizeof(List)); //分配存储单元
    s->Data = X;
    s->Next = PtrL;
    return s;
  }
 p = FindKth( i-1, PtrL);    //查找第i-1个结点
 if( p == NULL){               //结点不存在
    printf( "参数i错误! " );
    return NULL;
  }else{                //结点存在,分配存储单元后直接插入i-1个结点的后面
     s=(List *)malloc(sizeof(List));
     s->Data = X;
     s->Next = p->Next;
     p->Next = s;
     return PtrL;
   }
}

总结一下原理~~
1.先构造一个新结点,用s指向;
2.再找到链表的第i-1个结点,用p指向;
3.修改指针,插入结点。

其中值得注意的是
s->Next = p->Next; p->Next = s;
这两步不能交换,如果先进行了后者,则p的后一个结点则不存在~~~

4.删除操作

List *Delete( int i,List *PtrL){
    List *p, *s;
    if( i == 1){          //删除第一个结点
     s=PtrL;        //s指向第一个结点
     if( PtrL != NULL) PtrL = PtrL -> Next;   //直接覆盖掉~~
     else return NULL;         
     free( s );       //释放内存
     return PtrL;
   }
    p = FindKth( i-1,PtrL );    //查找第i-1个结点
    if( p == NULL){                //不存在的情况
         printf("第%d个结点不存在 ",i-1); return NULL; 
     }else if (p->Next == NULL){
         printf("第%d个结点不存在",i);  return NULL;
 }else{
     s = p->Next;                        //s指向第i个结点
     p->Next = s->Next;             //删除~!~
     free(s);                            
     return PtrL; 
}
}

总结一下链表的删除操作~~
1.先找到链表的第i-1个结点,用p指向;
2.再用指针s指向要被删除的结点 p->Next;

  1. 修改指针,删除s所指结点
    4.释放s所指结点的空间~

that's all~~~

66人推荐
随时随地看视频
慕课网APP

热门评论

有没有好心人帮我,完全不懂

想要学习这些需要什么样的基础

有没有具体运行的线性表基本函数,不知道怎么编程

查看全部评论