⚡ 第二.三章顺序表与链表⚡

线性表

线性表

线性表:具'有相同数据类型'的n个数据元素的`有限序列`

线性表 的特点如下:
表中元素 的个数有限 。
表中元素具有逻辑上的顺序性 ,
表中元素有其先后次序。
表中元素都是数据元素,每个元素都是单个元素。
表中元素的数据类型都相同,这意味着每个元素占有相同大小的存储空间 。

顺序表

顺序表
线性表的顺序存储又称顺序表。它是用一组地址连续的存储单元
依次存储线性表中的数据元

素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。

顺序表的基本操作


插入

bool ListInsert(SqList &L,int i,ElemType e){
    if(i<1 || i>L.length+i){
        return false;       //判断是否在有效范围
    }
    if (L.length >= MaxSize){
        return false;
    }
    for(int j=L.length; j>=i; j--){
        L.data[j] = L.data[j-1];    //将第i个元素及之后的元素后移
    }
    L.data[i-1] = e;    //在位置i放入e
    L.length++;
    return true;
}

最好情况:在表尾插入(i = n + 1 ),元素后移语句将不执行,时间复杂度为 0(1)。
最坏情况 :在表头插入( 即i = 1 ),元素后移语句将执行n次,时间复杂度为 O(n)。
平均情况是:n/2



删除操作

bool ListDelete(SqList &L,int i,ElemType &e){
    if(i<1 || i>L.length+i){
        return false;       //判断是否在有效范围
    }
    e = L.data[i-1];    //将被删除的元素赋值给e
    
    for(int j=i; i<L.length; j++){
        L.data[j-1] = L.data[j];    //将第i个位置后的元素前移
    }
    L.length--;
    return true;
}

最好情况:删除表尾元素(i = n),无须移动元素 ,时间复杂度为 0(1)。
最坏情况:删除表头元素(i = 1 ) ,需移动除第一个元素外的所有元素 ,时间复杂度为 O(n)。
平均情况:(n-1)/2


查找操作

int LocateElem(SqLsit L,ElemType e){
    int i;
    for(int i=0; i<L.length; i++){
        if(L.data[i] == e){
            return i+1;     //返回位序
        }
    }
    return 0;
}

最好情况:查找的元素就在表头,仅需 比较-次 ,时间复杂度为 0(1 ) 。
最坏情况 :查找的元素在表尾(或不存在),需要比较 n 次,时间复杂度为0(n) 。
平均情况:(n+1)/2


链表

链表

链表的基本操作

单链表头插法建立链表

LinkList List_HeadInsert(LinkList &L){
    LNode *s;
    int x;
    L = (LinkList)malloc(sizeof(LNode));    //创建头结点
    L->next = NULL;
    scanf("%d",&x);
    while (x != 99){
        s = (LNode*)malloc(sizeof(LNode));
        s->data = x;
        s->next = L->next;
        L->next = s;    //将新节点插入表中,L为头指针
        scanf("%d",&x);
    }
    return L;
}

单链尾插法建立链表

LinkList List_TailInsert(LinkList &L){
    LNode *s,*r=L;      //r为尾指针
    int x;
    L = (LinkList)malloc(sizeof(LNode));    //创建头结点
    L->next = NULL;
    scanf("%d",&x);
    while (x != 99){
        s = (LNode*)malloc(sizeof(LNode));
        s->data = x;
        r->next = s;    
        r = s;          //r指向新的表尾节点
        scanf("%d",&x);
    }
    r->next = NULL;
    return L;
}

插入节点操作

    s->next = p->next
    p->next = s;

删除节点操作

      q = p->next;      //q为替死鬼      
      p->next = q->next;      //将*q节点从链中断开
      free(q);            //释放空间

双链表


插入节点操作

      s->next = p->next;
      p->next->prior = s;
      s->prior = p;
      p->next = s;

删除节点操作

      p->next = q->next;
      q->next->prior = p;
      free(q);

循环双链表

在循环双链表 L 中,某结点叩为尾结点时,p->next==L;当循环双链表为空表时,其头结点的 prior 域和 next 域都等于 L 。


静态链表

静态链表 以 next==-1 作为其结束 的标志。静态链表的插入 、删除操作与动态链衰的相同,
只需要修改指针,而不需要移动元素 。

以上图片部分来自王道数据结构书中

posted @ 2020-07-30 14:25  xiaoff  阅读(188)  评论(0编辑  收藏  举报