zoukankan      html  css  js  c++  java
  • 2. 线性表 (算法和数据结构笔记)

    2. 线性表

    ● 线性表的顺序存储_SqList

    //起始部分

    #include "stdio.h"

    #include "stdlib.h"

    #include "io.h"

    #include "math.h"

    #include "time.h"

     

    #define OK 1

    #define ERROR 0

    #define TRUE 1

    #define FALSE 0

     

    #define MAXSIZE 20 /* 存储空间初始分配量*/

     

    typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等*/

    typedef int ElemType; /* ElemType类型根据实际情况而定,这里假设为int */

     

    //输出数据元素的值

    Status visit(ElemType c)

    {

        printf("%d ",c);

        return OK;

    }

     

    线性表的存储结构需要具备:

    数组[MAXSIZE];

    线性表的当前长度

    typedef struct

    {

        ElemType data[MAXSIZE]; /* 数组,存储数据元素*/

        int length; /* 线性表当前长度*/

    }SqList;

     

    //严蔚敏书上的代码(后面简称"严代码"):

    #define LIST_INIT_SIZE 100    //线性表存储空间的初始分配量

    #define LISTINCREMENT 10 //线性表存储空间的分配增量

    typedef struct{

        ElemType *elem;    //存储空间基址

        int length;    //当前长度

        int listsize; //当前分配的存储容量(siseof(ElemType)为单位)

    }SqList;

     

    /* 初始化顺序线性表*/

    Status InitList(SqList *L)

    {

        L->length=0;

        return OK;

    }

    分配基地址→分配失败的处理

    设置空表长度为;

    将存储容量初始化为LIST_INIT_SIZE

     

    //严代码:

    Status InitList_Sq(SqList &L) { // 算法.3

        // 构造一个空的线性表L

        L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));

        if (!L.elem) return OK; // 存储分配失败

        L.length = 0; // 空表长度为

        L.listsize = LIST_INIT_SIZE; // 初始存储容量

        return OK;

    } // InitList_Sq

     

    /* 初始条件:顺序线性表L已存在,≤iListLength(L) */

    /* 操作结果:用e返回L中第i个数据元素的值,注意i是指位置,第个位置的数组是从开始*/

    说明不能查找的情况: L.length==0 || i<1 || i>L.length;

    取出[i-1]下标的值

     

    Status GetElem(SqList L,int i,ElemType *e)

    {

        if(L.length==0 || i<1 || i>L.length) //length==0的意思是线性的的长度(不是线性表的容量)为, 即线性表中一个元素也没有

            return ERROR;

        *e=L.data[i-1];

     

        return OK;

    }

     

    /* 初始条件:顺序线性表L已存在*/

    /* 操作结果:返回L中第个与e满足相等关系的数据元素的位序。*/

    /* 若这样的数据元素不存在,则返回值为*/

    如果表的length等于零, 或者i大于表的length, 返回;

    遍历表, 找到了就break, 然后返回i+1的值.

    int LocateElem(SqList L,ElemType e)

    {

        int i;

        if (L.length==0 || i>=L.length)

        for(i=0;i<L.length;i++)

        {

            if (L.data[i]==e)

                break;

        }

        return i+1;

    }

     

    /* 初始条件:顺序线性表L已存在,1≤iListLength(L)*/

    /* 操作结果:在L中第i个位置之前插入新的数据元素eL的长度加*/

    如果插入位置不合理,抛出异常;

    如果线性表长度大于等于数组长度,则抛出异常或动态增加容量;

    从最后一个元素开始向前遍历到第i个位置,并且将这些元素都分别向后移动一个位置;

    将要插入元素填入位置i

    表长加。

    Status ListInsert(SqList *L,int i,ElemType e)

    {

        int k;

        if (L->length==MAXSIZE) /* 顺序线性表已经满*/

            return ERROR;

        if (i<1 || i>L->length+1)/* 当i比第一位置小(例如i=0的情况)或者比最后一位置后一位置还要大时*/

            return ERROR;

     

        if (i<=L->length) /* 若插入的数据的位置不在表尾*/

        {

            for(k=L->length-1;k>=i-1;k--) /* 将要插入位置之后的数据元素向后移动一位*/

                L->data[k+1]=L->data[k]; /* 第一次循环是将data[2]赋值给data[1] */

        }

        L->data[i-1]=e; /* 将新元素插入*/

        L->length++;

     

        return OK;

    }

     

    /* 初始条件:顺序线性表L已存在,≤iListLength(L) */

    /* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减*/

    如果删除位置不合理,抛出异常;

    取出删除元素;

    从删除元素位置开始遍历到最后一个元素位置,并且将它们都分别向前移动一个位置;

    表长减。

    Status ListDelete(SqList *L,int i,ElemType *e)

    {

        int k;

        if (L->length==0) /* 线性表为空*/

            return ERROR;

        if (i<1 || i>L->length) /* 删除位置不正确*/

            return ERROR;

        *e=L->data[i-1]; /* 第i个元素的下标为i-1 */

        if (i<L->length) /* 如果删除的数据不在表尾*/

        {

            for(k=i;k<L->length;k++)/* 将删除位置后继元素前移*/

                L->data[k-1]=L->data[k];

        }

        L->length--;

        return OK;

    }

     

    /* 初始条件:顺序线性表L已存在*/

    /* 操作结果:依次对L的每个数据元素输出*/

    思路:

    循环调用visit()函数.

    Status ListTraverse(SqList L)

    {

        int i;

        for(i=0;i<L.length;i++)

            visit(L.data[i]);

        printf("n");

        return OK;

    }

     

    //将所有在线性表Lb中出现但不在La中的数据元素插入到La

    声明两个表的长度的变量;

    声明两个表的相同元素的变量;

    求出两个表的长度;

    用插入表的长度进行循环, 在循环体中, 先取出插入表的一个元素, 如果取出的元素不存在于被插入表中, 那么就插入被插入表.

    void unionL(SqList *La,SqList Lb)

    {

        int La_len,Lb_len,i;

        ElemType e;        /* 声明与LaLb相同的数据元素e */

        La_len=ListLength(*La);        /* 求线性表的长度*/

        Lb_len=ListLength(Lb);

        for (i=1;i<=Lb_len;i++)

        {

            GetElem(Lb,i,&e);        /* 取Lb中第i个数据元素赋给e */

            if (!LocateElem(*La,e))        //相当于if(LocateElem(*La,e)==0)

                ListInsert(La,++La_len,e);    //插入

        }

    }

     

    //主函数

    int main()

    {

     

        SqList L;

        ElemType e;

        Status i;

        int j,k;

        i=InitList(&L);

        printf("初始化L后:L.length=%dn",L.length);

        for(j=1;j<=5;j++)

            i=ListInsert(&L,1,j);

        printf("在L的表头依次插入~后:L.data=");

        ListTraverse(L);

     

        printf("L.length=%d n",L.length);

        i=ListEmpty(L);

        printf("L是否空:i=%d(1:是0:否)n",i);

     

        i=ClearList(&L);

        printf("清空L后:L.length=%dn",L.length);

        i=ListEmpty(L);

        printf("L是否空:i=%d(1:是0:否)n",i);

     

        for(j=1;j<=10;j++)

            ListInsert(&L,j,j);

        printf("在L的表尾依次插入~后:L.data=");

        ListTraverse(L);

     

        printf("L.length=%d n",L.length);

     

        ListInsert(&L,1,0);

        printf("L的表头插入后:L.data=");

        ListTraverse(L);

        printf("L.length=%d n",L.length);

     

        GetElem(L,5,&e);

        printf("第个元素的值为:%dn",e);

        for(j=3;j<=4;j++)

        {

            k=LocateElem(L,j);

            if(k)

                printf("%d个元素的值为%dn",k,j);

            else

                printf("没有值为%d的元素n",j);

        }

     

     

        k=ListLength(L); /* k为表长*/

        for(j=k+1;j>=k;j--)

        {

            i=ListDelete(&L,j,&e); /* 删除第j个数据*/

            if(i==ERROR)

                printf("删除第%d个数据失败n",j);

            else

                printf("删除第%d个的元素值为:%dn",j,e);

        }

        printf("依次输出L的元素:");

        ListTraverse(L);

     

        j=5;

        ListDelete(&L,j,&e); /* 删除第个数据*/

        printf("删除第%d个的元素值为:%dn",j,e);

     

        printf("依次输出L的元素:");

        ListTraverse(L);

     

        //构造一个有个数的Lb

        SqList Lb;

        i=InitList(&Lb);

        for(j=6;j<=15;j++)

            i=ListInsert(&Lb,1,j);

     

        unionL(&L,Lb);

     

        printf("依次输出合并了LbL的元素:");

        ListTraverse(L);

     

        return 0;

    }

     

     

    ● 线性表链式存储_LinkList

    //起始部分

    #include "stdio.h"

    #include "string.h"

    #include "ctype.h"

    #include "stdlib.h"

    #include "io.h"

    #include "math.h"

    #include "time.h"

     

    #define OK 1

    #define ERROR 0

    #define TRUE 1

    #define FALSE 0

     

    #define MAXSIZE 20 /* 存储空间初始分配量*/

    typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等*/

    typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */

     

    //输出数据元素的值

    Status visit(ElemType c)

    {

        printf("%d ",c);

        return OK;

    }

     

    //单链表的存储结构:

    数据域; 指针域

    typedef struct Node

    {

        ElemType data;

        struct Node *next;    //nextNode结构体指针类型的

    }Node;

     

    typedef struct Node *LinkList; /* LinkList表示struct Node* */

     

    /* 初始化单链表*/

    将一个sizeof(Node)的空间分配给*L;

    如果分配失败, 返回异常;

    将指针域设置为NULL;

    返回OK, .

    Status InitList(LinkList *L)

    {

        *L=(LinkList)malloc(sizeof(Node)); /* 分配一个节点的空间, 产生头结点,并使L指向此头结点*/

        //Lstruct Node** 类型的, L是一个二级指针, *L表示取L指针指向的变量的内容--一个struct Node*类型的指针

        if(!(*L)) /* 存储分配失败, if((*L)=0) */

            return ERROR;

        (*L)->next=NULL; /* 指针域为空*/

     

        return OK;

    }

     

    /* 初始条件:单链表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */

     

    Status ListEmpty(LinkList L)

    {

        if(L->next)

            return FALSE;

        else

            return TRUE;

    }

     

    /* 初始条件:单链表L已存在。操作结果:将L重置为空表(清空, 不是销毁)*/

    1. 声明LinkList型变量pq, p指向单链表的第一个结点(不是头结点);
    2. p!=0时, 进入循环体--q来临时记录p的后继结点; 释放掉第一个头结点, free(p); 将q赋值给p如此继续循环;
    3. 循环结束后, 将头节点的指针域赋值为空.

    注意: 总之, 我们要保留头结点, 然后将后面的结点一一删除, 最后将头结点的指针域赋值为空. 在此之后, 这个链表还存在,可以继续使用.

    Status ClearList(LinkList *L)

    {

        LinkList p,q;

        p=(*L)->next; /* p指向第一个结点*/

        while(p) /* 没到表尾*/

        {

            q=p->next;        //q用来临时记录p的后继结点

            free(p);

            p=q;

        }

        (*L)->next=NULL; /* 头结点指针域为空*/

        return OK;

    }

     

    //销毁:

    1. 声明一个LinkList型的指针q;
    2. (*L)!=0时, 进入循环体--q指向单链表的第一个结点, (*L)->next; 释放掉指针(*L)指向的头结点的内容; (*L)指针指向q结点如此继续循环把后面的结点都删除

    注意: 指针被free掉之后只是指针指向的那一部分空间被释放掉了,而指针本身就是一种指针变量,除非程序运行结束或其生存期结束了才消失!因此只要程序还在运行,该指针就可以再赋值!

    例如free(p);

    p=NULL;

    是合法的, 但是如果你要访问*p则会出错.

     

    Status DestroyList(LinkList *L)

    { /* 初始条件:线性表L已存在。操作结果:销毁线性表L */

        LinkList q;

        while(*L)

        {

            q=(*L)->next;

            free(*L);

            *L=q;

        }

        return OK;

    }

     

    /* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数*/

    声明一个变量i用来计数;

    声明一个LinkList型的变量p, 并指向单链表的第一个结点, L->next;

    p!=0, 进入循环, 在循环体内, 先将i, 然后将指针p指向p的后继结点, 如此继续循环;

    返回i.

    int ListLength(LinkList L)

    {

        int i=0;

        LinkList p=L->next; /* p指向第一个结点*/

        while(p)

        {

            i++;

            p=p->next;

        }

        return i;

    }

     

    /* 初始条件:单链表L已存在,≤iListLength(L) */

    /* 操作结果:用e返回L中第i个数据元素的值*/

    声明一个LinklList指针p指向链表的第一个结点(不是头结点);

    声明变量j作为计数器从开始;

    j<i时,就遍历链表--p指针不断指向下一结点,j不断累加1

    若到链表末尾时p为空,则说明第i个结点不存在;

    否则查找成功,返回结点p的数据。

    Status GetElem(LinkList L,int i,ElemType *e)

    {

        int j= 1        /* j为计数器*/

        LinkList p;        /* 声明一结点p */

        p = L->next;        /* p指向链表L的第一个结点*/

        while (p && j<i) /* p不为空或者计数器j还没有等于i时,循环继续*/

        {

            p = p->next; /* p指向下一个结点*/

            ++j;

        }

        if ( !p || j>i )

            return ERROR; /* i个元素不存在*/

        *e = p->data; /* 取第i个元素的数据*/

        return OK;

    }

     

    /* 初始条件:顺序线性表L已存在*/

    /* 操作结果:返回L中第个与e满足相等关系的数据元素的位序。*/

    /* 若这样的数据元素不存在,则返回值为*/

    声明一个LinkList型指针p指向链表第一个结点;

    声明变量i作为计数器从0开始;

    p!=0,先将i, 如果此时p的数据域等于e,那么就返回i, 否则将p指针指向下一结点;

    退出循环后返回.

    int LocateElem(LinkList L,ElemType e)

    {

        LinkList p=L->next;

        int i=0;    //i是计数器

        while(p)

        {

            i++;

            if(p->data==e) /* 找到这样的数据元素*/

                return i;

            p=p->next;

        }

     

        return 0;

    }

     

    /* 初始条件:顺序线性表L已存在,1≤iListLength(L) */

    /* 操作结果:在L中第i个位置之前插入新的数据元素eL的长度加*/

    ①声明两个LinkList型指针ps, p指向链表第一个结点(不是首节点);

    ②声明变量j作为计数器从1开始;

    ③当p不为空且j<i时,就遍历链表----p指针不断指向下一结点,j不断累加1;

    ④当p==0或j>i,说明第i个元素不存在, 返回ERROR;

    ⑤分配一个LinkList型的新节点s;

    ⑥将e赋值给s结点的数据域;

    ⑦把s结点的指针域指向p的后继结点(p的后继结点变成s的后继结点);

    ⑧把p结点的指针域指向s结点(s结点变成p的后继结点)

    ⑨返回OK, 即1.

    : 因为这里没有指向p结点的后继结点的指针, 所以用p->next来代表p的后继结点.

    Status ListInsert(LinkList *L,int i,ElemType e)

    {

        

        LinkList p,s;

        int j;

        p = *L;

        j = 1;

        while (p && j < i) /* 寻找第i个结点*/

        {

            p = p->next;

            ++j;

        }

        if (!p || j > i)

            return ERROR; /* i个元素不存在*/

        s = (LinkList)malloc(sizeof(Node)); /* 生成新结点(C语言标准函数) */

        s->data = e;

        s->next = p->next; /* p的后继结点赋值给s的后继 */

        p->next = s; /* s赋值给p的后继*/

        return OK;

    }

     

    /* 初始条件:顺序线性表L已存在,≤iListLength(L) */

    /* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减*/

    声明两个LinkList型指针pq, p指向链表的首节点(不是链表的第一个结点), q在下面用来代表欲删除的结点;

    声明变量j作为计数器从开始;

    p->next不为空,j<i时,就遍历链表-- p指针向后移动,不断指向下一个结点, j不断累加;

    如果p->next为空, j>i,说明第i个元素不存在, 返回ERROR;

    否则说明查找到了与删除的结点, q指向p的后继结点(欲删除的结点), q=q->next;

    p结点的指针域指向q的后继结点;

    q结点的指针域赋值给*e, 然后释放q;

    返回OK.

    : 我们这里只有qp指针分别指向欲删除的结点和欲删除结点前的结点, 至于欲删除节点后的结点用q->next来表示.

    Status ListDelete(LinkList *L,int i,ElemType *e)

    {

        

        LinkList p,q;

        p = *L;

        int j= 1;

        while (p->next && j < i)    /* 遍历寻找第i个元素*/

        {

            p = p->next;

            ++j;

        }

        if (!(p->next) || j > i)

            return ERROR; /* 第i个元素不存在*/

        q = p->next;

        p->next = q->next;            /* 将q的后继赋值给p的后继*/

        *e = q->data; /* 将q结点中的数据给e */

        free(q); /* 让系统回收此结点,释放内存*/

        return OK;

    }

     

    /* 初始条件:顺序线性表L已存在*/

    /* 操作结果:依次对L的每个数据元素输出*/

    声明一个LinkList型的指针变量p指向单链表的第一个结点(不是头结点);

    当指针p!=0, 首先读取p指向的数据节点的数据域, 然后将p指针指向下一个结点(p->next), 如此继续循环.

    Status ListTraverse(LinkList L)

    {

        LinkList p=L->next;

        while(p)

        {

            visit(p->data);

            p=p->next;

        }

        printf("n");

        return OK;

    }

     

    /* 随机产生n个元素的值,建立带表头结点的单链线性表L(头插法)*/

    ①声明一个LinkList型的指针p和计数器变量i;

    ②初始化随机数种子;

    ③分配sizeof(Node)大小的内存(Linklist型), 并赋值给*L, 从而初始化了一个空链表L;

    ④让L的头结点的指针指向NULL,即建立一个带头结点的单链表;

    ⑤循环:

    生成一新结点赋值给p;

    随机生成一个数字并赋值给p的数据域p->data;

    将p插入到头结点与前一新结点之间。

     

    注意:

    LinkList p;    //p是struct Node*类型的

    LinkList *L;    //L是struct Node**类型的, 所以*L是struct Node*类型的

    和单链表相关的函数的形参有可能是LinkList型的或LinkList*的, 要表示单链表的头结点可分别用L或*L, 要表示单链表的第一个结点(不是头结点)可分别用L->next或(*L)->next;

     

    void CreateListHead(LinkList *L, int n)

    {

        LinkList p;

        int i;

        srand(time(0)); /* 初始化随机数种子*/

        *L = (LinkList)malloc(sizeof(Node));

        (*L)->next = NULL; /* 先建立一个带头结点的单链表*/

        for (i=0; i<n; i++)

        {

            p = (LinkList)malloc(sizeof(Node)); /* 生成新结点*/

            p->data = rand()%100+1; /* 随机生成以内的数字*/

            p->next = (*L)->next;

            (*L)->next = p;                        /* 插入到表头*/

        }

    }

     

    /* 随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法)*/

    void CreateListTail(LinkList *L, int n)

    {

        LinkList p,r;

        int i;

        srand(time(0)); /* 初始化随机数种子*/

        *L = (LinkList)malloc(sizeof(Node)); /* L为整个线性表*/

        r=*L; /* r为指向尾部的结点*/

        for (i=0; i<n; i++)

        {

            p = (Node *)malloc(sizeof(Node));  /* 生成新结点*/

            p->data = rand()%100+1; /* 随机生成以内的数字*/

            r->next=p; /* 将表尾终端结点的指针指向新结点*/

            r = p; /* 将当前的新结点定义为表尾终端结点*/

        }

        r->next = NULL; /* 表示当前链表结束*/

    }

     

    int main()

    {

        LinkList L;

        ElemType e;

        Status i;

        int j,k;

        i=InitList(&L);

        printf("初始化L后:ListLength(L)=%dn",ListLength(L));

        for(j=1;j<=5;j++)

            i=ListInsert(&L,1,j);

        printf("在L的表头依次插入~后:L.data=");

        ListTraverse(L);

     

        printf("ListLength(L)=%d n",ListLength(L));

        i=ListEmpty(L);

        printf("L是否空:i=%d(1:是0:否)n",i);

     

        i=ClearList(&L);

        printf("清空L后:ListLength(L)=%dn",ListLength(L));

        i=ListEmpty(L);

        printf("L是否空:i=%d(1:是0:否)n",i);

     

        for(j=1;j<=10;j++)

            ListInsert(&L,j,j);

        printf("在L的表尾依次插入~后:L.data=");

        ListTraverse(L);

     

        printf("ListLength(L)=%d n",ListLength(L));

     

        ListInsert(&L,1,0);

        printf("L的表头插入后:L.data=");

        ListTraverse(L);

        printf("ListLength(L)=%d n",ListLength(L));

     

        GetElem(L,5,&e);

        printf("第个元素的值为:%dn",e);

        for(j=3;j<=4;j++)

        {

            k=LocateElem(L,j);

            if(k)

                printf("%d个元素的值为%dn",k,j);

            else

                printf("没有值为%d的元素n",j);

        }

     

     

        k=ListLength(L); /* k为表长*/

        for(j=k+1;j>=k;j--)

        {

            i=ListDelete(&L,j,&e); /* 删除第j个数据*/

            if(i==ERROR)

                printf("删除第%d个数据失败n",j);

            else

                printf("删除第%d个的元素值为:%dn",j,e);

        }

        printf("依次输出L的元素:");

        ListTraverse(L);

     

        j=5;

        ListDelete(&L,j,&e); /* 删除第个数据*/

        printf("删除第%d个的元素值为:%dn",j,e);

     

        printf("依次输出L的元素:");

        ListTraverse(L);

     

        i=ClearList(&L);

        printf("n清空L后:ListLength(L)=%dn",ListLength(L));

        CreateListHead(&L,20);

        printf("整体创建L的元素(头插法)");

        ListTraverse(L);

     

        i=ClearList(&L);

        printf("n删除L后:ListLength(L)=%dn",ListLength(L));

        CreateListTail(&L,20);

        printf("整体创建L的元素(尾插法)");

        ListTraverse(L);

     

     

        return 0;

    }

     

    ● 静态链表_StaticLinkList

    //静态链表和单链表的对应关系如下图:

    注:①静态链表以next==-1作为其结束的标志。

    ②静态链表的插入、删除操作与动态链表相同,只需要修改指针,而不需要移动元素。

    ③总体来说,静态链表没有单链表使用起来方便,但是在一些不支持指针的高级语言(如Basic)中,这又是一种非常巧妙的设计方法。

    //静态链表结构类型的描述

    #define MaxSize 50 //静态链表的最大长度

    typedef struct{ //静态链表结构类型的定义

        ElemType data; //存储数据元素

        int next; //下一个元素的数组下标; 有的资料用的是

    }SLinkList[MaxSize];

     

    ● 循环链表

    //. 循环链表的案例

    /* 有两个循环链表AB, 其尾指针分别是rearArearB, 它们分别指向表A和表B的头结点*/

    /* 先要求合并循环列表AB */

    声明两个LinkList型的变量pq;

    将指针p指向链表A的头结点;

    rearA结点的指针域指向rearB的第一个结点;

    ④释放B表的头结点

    rearB的指针域指向链表A的头结点

    LinkList Connect(LinkList A,LinkList B)

    {//假设AB为非空循环链表的尾指针

        LinkList p;

        LinkList p=A->next;//将指针p指向链表A的头结点

        A->next=B->next->next;//rearA结点的指针域指向rearB的第一个结点

        free(B->next);//释放B表的头结点

        B->next=p;//rearB的指针域指向链表A的头结点

        return B;//返回新循环链表的尾指针

    }

     

    ● 双向链表

    /* 线性表的双向链表存储结构*/

    包括: 数据域, 前驱指针域, 后继指针域

    typedef struct DulNode

    {

        ElemType data;

        struct DuLNode *prior; /* 直接前驱指针*/

        struct DuLNode *next; /* 直接后继指针*/

    } DulNode, *DuLinkList;

     

    //双向列表的插入

    /* p赋值给s的前驱,如图中*/

    s->prior = p;

    /* p->next赋值给s的后继,如图中*/

    s->next = p->next;

    /* s赋值给p->next的前驱,如图中*/

    p->next->prior = s;

    /* s赋值给p的后继,如图中*/

    p->next = s;

     

    //双向列表的删除

    /* p->next赋值给p->prior的后继,如图中*/

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

    /* p->prior赋值给p->next的前驱,如图中*/

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

    /* 释放结点*/

    free(p);

     

  • 相关阅读:
    HDU 5671 矩阵
    HDU 5670
    UVA 11995 STL 使用
    VK Cup 2016
    字段定义
    apache用户
    apache
    使用第三方登录
    setex()
    如果客户端禁用了cookie,如何实现session
  • 原文地址:https://www.cnblogs.com/ArrozZhu/p/8388365.html
Copyright © 2011-2022 走看看