《大话数据结构》第三章 线性表

**

第三章 线性表

**
有序、有限、最多一个前驱和一个后继
基本操作:
InitList(&L)
ListEmpty(L)
ClearList(&L)
GetElem(L, i, &e)
LocateElem(L, e)
ListInsert(&L, i, e)
ListDelete(&L, i, &e)
ListLength(L)

线性表集合A和B的合并操作

/*将所有的在线性表Lb中,但不在La中的数据元素插入到La中*/
void union(List *La, List Lb)
{
    int La_len, Lb_len;
    ElemType e;

    La_len = ListLength(La);
    Lb_len = ListLength(Lb);

    for(int i=1; i<=Lb_len; i++){
        GetElem(Lb,i,&e);
        if(!LocateElem(La,e))
        ListInsert(&La,++La_len,e); 
    }
} 

线性表的顺序存储的结构代码

#define MaxSize 20
typedef int ElemType
typedef struct{
    Elemtype data[MaxSize];
    int Length;
}SqList;

随机存取结构,其存取时间性能为O(1)

获得元素的操作

#define OK 1
#define ERROR 0
#define TRUE 1
#define FASLE 0
typedef int Status;

Status GetElem(SqList L, int i, ElemType *e){
    if(L.Length==0 || i<1 || i>L.Length)    
        return ERROR;
    *e=L.data[i-1];
    return OK;
}

插入操作

Statue ListInsert(SqList *L, int i, ElemType e){
    int k;
    if(L->Length == MaxSize)    
        return ERROR;
    if(i<1 || i>L->Length+1)
        return ERROR;
    if(i<=L->Length){
        for(k=L->Length-1; k>=i-1; k--)
            L->data[k+1] = L->data[k];
    }
    L->data[i-1]=e;
    L->Length++;
    return OK;
}

删除操作

Statue 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];
    if(i<L->Length){
        for(k=i-1; k<L->Length-1; k++)
            L->data[k]=L->data[k+1] 
    }
    L->Length--;
    return OK;
}

存取快,插入删除慢


链式存储结构
《大话数据结构》第三章 线性表_第1张图片
头指针是必要元素,头指针均不为空,但头结点不一定是链表的必要元素,头结点是为了操作的统一和方便设立的,放在第一元素节点前,数据域一般放链表长度
若线性表为空表,则头结点的指针域为空。

单链表的结构代码

typedef struct Node{
       //结点由数据域和指针域组成
    ElemType data;
    struct Node *next;
} Node, *LinkList;

单链表的读取

Status GetElem(LinkList L, int i, ElemType *e){
    //LinkList即为Node*
    int j;
    LinkList p;
    p=L->next;  //让p指向第一个结点,L理解为头结点的指针
    j=1;    //j为计数器

    while(p && j<i) //p不为空且计数器j还没等于i时,循环继续
    {
        p=p->next;
        j++;    
    }
    if(!p || j>i)
        return ERROR;

    *e=p->data;
    return OK; 
}

单链表的插入

Status LinkInsert(LinkList *L, int i, ElemType e){
    int j;
    LinkList p, s;
    p=*L;
    j=0;

    while(!p && j1){
        p=p->next;
        ++j;
    }

    if(!p || j>i-1)
        return ERROR;

    s=(LinkList)malloc(sizeof(Node));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return OK; 
}

单链表的删除

Status ListDelete(LinkList *L, int i, ElemType *e){
    int j;
    LinkList p, q;
    p=*L;
    j=0;

    while(p && j1){
        p=p->next;
        ++j; 
    }

    if(!p || j>i-1)
        return ERROR;
    if(!(p->next))
        return ERROR;

    q=p->next;
    p->next = q->next;
    *e = q->data;
    free(q);
    return OK
} 

创建单链表 头插法

void CreateListHead(LinkList *L, int n){
    LinkList p;
    int i;
    srand(time(0));
    *L =(LinkList)malloc(sizeof(Node));
    (*L)->next=NULL;
    for(int i=1; i<=n; i++){
        p=(LinkList)malloc(sizeof(Node));
        p->data = rand()%100+1;
        p->next = (*L)->next;
        (*L)->next = p; 
    }
}

创建单链表 尾插法

void CreateLinkTail(LinkList *L, int n){
    LinkList p, r;
    int i;
    srand(time(0));
    (*L)=(LinkList)malloc(sizeof(Node));
    r=*L;

    for(i=1; i<=n; i++){
        p = (LinkList)malloc(sizeof(Node));
        p->data = rand()%100+1;
        r->next = p;
        //p->next = r->next;
        r=p; 
    }
    r->next=NULL; 
}

单链表的整表删除

Status ClearList(LinkList *L)
{
    LinkList p,q;
    p=(*L)->next;

    while(p){
        q=p->next;
        free(p);
        p=q;
    } 
    (*L)->next=NULL;
    return OK;
}

静态链表
《大话数据结构》第三章 线性表_第2张图片
游标实现法

#define MaxSize 1000
typedef struct{
    ElemType data;
    int cur;    //游标cursor 
}Component, StaticLinkList[MaxSize];

初始化

Statues InitList(StaticLinkList space){
    int i;
    for(i=0; i1; i++)
        space[i].cur = i+1;
    space[i].cur = 0;
    return OK;
}
/*数组第一个元素的cur用来存放备用链表第一个节点的下标
把未被使用的数组元素成为备用链表,
下一位置数据为空则next0表示
数组的最后一个元素的cur用来存放第一个插入元素的下标,当整个链表为空时,为0*/ 

链表的插入操作

int Malloc_SLL(StaticLinkList space){
    int i=space[0].cur;

    if(space[0].cur)
        space[0].cur = space[i].cur;

    return i;
}

Status ListInsert(SaticLinkList L, int i, ElemType e){
    int j, k, l;
    k = MaxSize-1;
    j = Malloc_SLL(L);

    if(i<1 || i>ListLength(L)+1)
        return ERROR;

    if(j){
        L[j].data = e;
        for(l=1; l<=i-1; l++)
            k=L[k].cur;
        L[j].cur=L[k].cur;
        L[k].cur=j;
        return OK;
    }
    return ERROR;
}

int ListLength(StaticLinkList space){
    int j=0;
    int i=space[MaxSize-1].cur;

    while(i){
        j++;
        i=space[i].cur;
    }
    return j;
}

链表的删除操作

Status ListDelete(StaticLinkList L, int i){
    int j, k;
    k=MaxSize-1;

    if(i<1 || i>ListLength(L))
        return ERROR;

    for(j=1; j<=i-1; j++)
        k=L[k].cur;

    j=L[k].cur;
    L[k].cur=L[j].cur;
    Free_SSL(L,j);

    return OK;
}

void Free_SSL(StaticLinkList space, int k){
    space[k].cur=space[0].cur;
    space[0].cur=k;
}

int ListLength(StaticLinkList L){
    int j,k,i;
    i=L[Maxsize-1].cur;
    j=0;

    while(i){
        ++j;
        i=L[i].cur;
    }

    return j;
}

循环链表
设置循环链表的尾指针rear,便于访问尾结点
判断循环结束的条件 p->next 是否等于头结点
只用设置尾结点即可

合并两个链表的操作
《大话数据结构》第三章 线性表_第3张图片

p=rearA->next;
rearA->next=rearB->next->next;
rearB->next=p;
free(p);

双向链表
双向链表的存储结构
《大话数据结构》第三章 线性表_第4张图片

typedef struct DulNode
{
    ElemType data;
    struct DulNode *prior;
    struct DulNode *next;
} DulNode, *DuLinkList;

双向链表的插入s操作

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

Status DuListInsert(DuLinkList *L, int i, ElemType e){
    int j;
    DuLinkList p,s;
    p=*L;
    j=0;

    while(p->next && j<i){
        ++j;
        p=p->next;
    }

    if(!p || j>i)
        return ERROR;

    s=(DuLinkList)malloc(sizeof(DulNode));
    s->data=e;
    s->next=p;
    s->prior=p->prior;
    p->prior=s;
    s->prior->next=s;

    return OK;
}

双向链表的删除p操作

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

Status DuListDelete(DuLinkList *L, int i, ElemType *e){
    int j;
    DuLinkList p;
    p=*L;
    j=0;

    while(p->next && j<i){
        p=p->next;
        ++j;
    }

    if(!p || j>i)
        return ERROR;

    *e=p->data;
    p->next->prior = p->prior;
    p->prior->next = p->next;
    free(p);

    return OK;
}

你可能感兴趣的:(数据结构)