大话数据结构学习(2)线性表的链式存储结构

1、线性表的链式存储结构:n个结点(结点存数据元素和后继元素的指针),链接为一个链表,即为线性表(a1,a2,……,an)的链式存储结构。
2、链式存储结构的头指针①头指针是链表的必要元素!!无论链表是否为空,头指针均不为空。②头指针有标识作用,通常用来标识链表名。③头指针指向链表的第一个结点(头结点或第一个结点)。
3、头结点:①头结点不是必须的。②头结点是为了第一个元素前的插入或删除和后面元素一样,而设立的。放在第一个结点之前。数据域一般无意义,不过也可以存放链表长度。
4线性表的顺序存储结构链式存储结构的对比:
这里写图片描述
5、链式存储结构代码(以单链表为例)

/************************************************************************/
/*                  (2)线性链式存储                                     */
/************************************************************************/


#include <stdio.h>
#include <time.h>
#include <iostream>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MaxSize 30  //存储空间初始分配量
typedef int Status;
typedef int ElemType;

extern Status visit(ElemType c);


/*  线性表的单链表存储结构     */
typedef struct Node         //①定义Node结点:数据域+后继结点地址的指针域;
{
    ElemType data;
    struct Node *next;
}Node;                                      //②typedef struct Node Node:Node可替换为 struct Node

typedef struct Node *LinkList;      //定义LinkList链表,LinkList 可替换为 struct Node *

//初始化顺序线性表
Status InitList(LinkList *L)
{
    *L=(LinkList)malloc(sizeof(Node));      //产生头结点,并使L指向此头结点
    if(!(*L))                                               //存储分配失败
        return ERROR;                       
    (*L)->next =NULL;                           //令头结点的指针域为空
    return OK;
}


/*  初始条件:顺序线性表L已经存在 */
/*  操作结果:若L为空表,则返回TRUE,否则返回FALSE    */
Status ListEmpty(LinkList L)
{
    if (L->next == NULL)
        return TRUE;
    else
        return FALSE;
}

/*  初始条件:顺序线性表L已经存在 */
/*  操作结果:将L重置为空表    */
Status ClearList(LinkList L)
{
    LinkList p,q;
    p=(*L).next;        //p指向第一个节点
    while(p)                //若p不为空,表示还没到表尾,一直while循环
    {
        q=p->next;
        free(p);            //释放每一个结点所占的内存空间
        p=q;
    }
    (*L).next = NULL;   //  将头结点指针域置为空
    return OK;
}

/*  初始条件:顺序线性表L已经存在 */
/*  操作结果:返回L中数据元素的个数*/
int ListLength(LinkList L)
{
    int k=0;
    LinkList p=L->next; //p指向L表的第一个结点
    while(p)
    {
        k++;
        p=p->next;
    }
    return k;
}



/*  初始条件:顺序线性表已经存在,且1<=i<=LineList(L)   */
/*  操作结果:用e返回L中第i个数据元素的值    */
Status GetElem(LinkList L, int i,ElemType *e)
{
    int j;
    LinkList p;     //声明一个结点p
    p=L->next;  //p指向链表的第一个结点
    j=1;
    while(p && j<i)
    {
        p=p->next;
        j++;
    }
    if (!p || j>i)          //如果p为空,或j>i,则第i个元素不存在
        return ERROR;
    *e = p->data;       //否则,第i个数据存在,取出即可
    return OK;

}


/*  初始条件:顺序线性表L已经存在 */
/*  操作结果:返回L中第1个与e满足关系的数据元素的位序*/
int LocateElem(LinkList L,ElemType e)
{
    int i=0;
    LinkList p=L->next;
    while(p)
    {
        i++;
        if (e==p->data)
            return i;
        else
            p=p->next;

    }
    return 0;
}

/*  初始条件:顺序线性表L已经存在 */
/*  操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(LinkList *L,int i,ElemType e)
{
    int j;
    LinkList p,s;
    p=*L;
    j=1;
    while(p && j<i)
    {
        j++;
        p=p->next;
    }

    if (!p || j>i)
        return ERROR;   //第i个元素不存在
    s = (LinkList) malloc(sizeof(Node));    //生成新结点
    s->data =e;
    s->next=p->next;
    p->next =s;
    return OK;

}


/*  初始条件:线性顺序表L已经存在     */
/*  操作结果:删除L的第i个位置的数据元素,并用e返回其值,L的长度减1*/
Status ListDelete(LinkList *L,int i,ElemType *e)
{
    int j;
    LinkList p,q;
    p=*L;
    j=1;
    while(p->next && j<i)
    {
        j++;
        p=p->next;
    }
    if (!(p->next) || j>i)
        return ERROR;
    q=p->next;
    p->next=q->next;
    *e=q->data;
    free(q);    //系统回收该结点,释放内存
    return OK;
}


/*  初始条件:顺序线性表L已经存在 */
/*  操作结果:依次对L的每个元素输出*/
Status ListTraverse(LinkList L)
{
    LinkList p=L->next; //p指向第一个结点
    while(p)
    {
        visit(p->data);
        p=p->next;
    }
    printf("\n");
    return OK;

}


/*随机产生n个元素的值,建立带表头结点的单链线性表L(头插法)*/
void CreateListHead(LinkList *L,int n)
{
    LinkList p;
    int i;
    srand(time(0)); //srand:产生随机数,初始化随机数种子
    *L=(LinkList) malloc(sizeof(Node));     //这句和下句,是生成一个新结点表示头结点,指向NULL表示只有头结点
    (*L)->next=NULL;    //先建立一个带头结点的单链表
    for (i=0;i<n;i++)
    {
        p=(LinkList)malloc(sizeof(Node));   //生成新的结点
        p->data=rand()%100+1;
        p->next=(*L)->next; //令p->next=NULL,从表头插入
        (*L)->next = p;     //插入到表头

    }

}
/*      尾插法     */
void CreateListTail(LinkList *L,int n)
{
    LinkList p,r;
    srand(time(0));
    *L = (LinkList)malloc(sizeof(Node));
    r=(*L);
    for(int i=0;i<n;i++)
    {
        p=(LinkList)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)=%d\n",ListLength(L));

    for (j=1;j<=5;j++)
    {
        i=ListInsert(&L,1,j);
    }
    printf("在表头依次插入1~5之后:L.data=");
    ListTraverse(L);

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

    i=ClearList(L);
    i=ListEmpty(L);
    printf("ClearList之后,L是否为空:i=%d(1:是;0:否)",i);

    printf("\n");
    for (j=1;j<=10;j++)
    {
        ListInsert(&L,j,j);
    }
    printf("在L的表尾依次插入1~10之后,L.data=");
    ListTraverse(L);
    printf("ListLength(L)=%d",ListLength(L));

    GetElem(L,5,&e);
    printf("第5个元素为:%d\n",e);


    for(j=3;j<=4;j++)
    {
        k=LocateElem(L,j);
        if(k)
            printf("第%d个元素值为%d\n",k,j);
        else
            printf("没有值为%d的元素\n",j);
    }


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

    for(j=k+1;j>=k;j--)
    {
        i=ListDelete(&L,j,&e);      //删除第j个数
        if (i == ERROR)
            printf("删除第%d个数据失败\n",j);
        else
            printf("要删除的第%d个数据为:%d",j,e);
    }
    printf("依次输出L中的元素:");
    ListTraverse(L);

    j=5;
    ListDelete(&L,j,&e);
    printf("要删除的第%d个数据为%d",j,e);
    printf("依次输出L中的元素:");
    ListTraverse(L);


    i=ClearList(L);
    printf("\n清空L后:ListLength(L)=%d\n",ListLength(L));
    CreateListHead(&L,5);
    printf("头插法:");
    ListTraverse(L);

    i=ClearList(L);
    printf("\n清空L后:ListLength(L)=%d\n",ListLength(L));
    CreateListTail(&L,5);
    printf("尾插法:");
    ListTraverse(L);


    getchar();
}

猜你喜欢

转载自blog.csdn.net/zhangying_496/article/details/81211629
今日推荐