线性表

来源:互联网 发布:建行软开待遇 知乎 编辑:程序博客网 时间:2024/05/21 01:55

线性表:顺序表和链表六种基本操作:

  1. InitList(&L)            //构造一个空的线性表L

  2. ListLength(L)           //获取线性表L的元素个数

  3. GetNode(L, i)           //获取线性表L第i个元素

  4. LocateNode(L, e)        //查找线性表值为e的元素的位置

  5. ListInsert(L, i, &e)    //在线性表L的第i个位置插入元素e

  6. DeleteNode(L, i)        //删除线性表L的第i个元素

一、顺序表

#define OK 1#define ERROR -1#define MAX_SIZE 100    //MAX_SIZE大小需根据具体情况而定,这里假设是100#typedef int Status;#typedef int ElemType;typedef struct sqlist{    ElemType Elem_array[MAX_SIZE];    int length;}SqList;

1.1 初始化

Status Init_SqList(SqList *L){    L->Elem_array = (ElemType *)malloc(MAX_SIZE*sizeof(ElemType));    if(!L->Elem_array)        return ERROR;    else    {        L->length = 0;        return OK;    }}

1.2 查找

int Locate_SqList(SqList *L, ElemType x) {     int i=0;     while(i<L->length)         if(L_Elem_array[i] != x)             i++;         else             return ++i;                    //要查找的值在线性表L第++i个位置      if(i>L->length)     {         printf(“要删除的数据元素不存在!\n”);        return ERROR;     }}

1.3 插入

Status Insert_SqList(SqList *L, int i, ElemType e) //在顺序表L中第i个位置插入元素e{    int j;    if(i<0||i>L->length-1)        return ERROR;    if(L->length>=MAX_SIZE)    {        printf("线性表溢出!\n");        return ERROR;    }    for(j=L->length-1; j>=i-1; --j)        L->Elem_array[j+1] = L->Elem_array[j]; //i-1位置以后的所以结点后移    L->Elem_array[i-1] = e; //在i-1位置插入结点e    L->length++;    return OK;}

1.4 删除

ElemType Delete_SqList(SqList *L, int i){    int k;    ElemType x;    if(L->length == 0)    {        printf("线性表L为空!\n");        return ERROR;    }    else if(i<1||i>L->length)    {        printf("要删除的数据元素不存在!\n");        return ERROR;    }    else    {        x = L->Elem_array[i-1];                      //保存结点的值        for(k=i; k<L->length; k++)            L->Elem_array[k-1] = L->Elem_array[k];  //i位置以后的所有结点前移        L->length--;        return x;    }}

二、单链表

typedef struct Lnode{    ElemType data;        //数据域,保存结点的值    struct Lnode *next;   //指针域}LNode;                  //结点类型

2.1 头插入法建表

/*头插入法创建单链表,链表的头结点head作为返回值*/LNode *create_LinkList(void){    int data;    LNode *head, *p;    head = (LNode *)malloc(sizeof(LNode));    head->next = NULL;                        //创建单链表头结点head    while(1)    {        scanf("%d", &data);                  //data值和类型可以根据具体情况得到        if(data == 32767)                    //32767定义为判断创建链表结束条件            break;        p = (LNode *)malloc(sizeof(LNode));        p->data = data;                      //数据域赋值        p->next = head->next;        head->next = p;                      //钩链,新创建的结点总是作为第一个结点    }    return head;}

2.2 尾插入法建表

/*尾插入法创建单链表,链表的头结点head作为返回值*/LNode *create_LinkList(void){    int data;    LNode *head, *p, *q;    head = p = (LNode *)malloc(sizeof(LNode));    p->next = NULL;                         //创建单链表头结点head    while(1)    {        scanf("%d", &data);                 //data值和类型可以根据具体情况得到        if(data == 32767)                   //32767定义为判断创建链表结束条件            break;        q = (LNode *)malloc(sizeof(LNode));        q->data = data;                     //数据域赋值        q->next = p->next;        p->next = q;        p = q;                              //钩链,新创建的结点总是作为第一个结点    }    return head;}

2.3 按序号查找

Elem_Type Get_Node(LNode *L, int i)  //在单链表L中查找第i个结点{    int j;    LNode *p;    p = L->next;    j = 1;         //使p指向第一个结点    while(p!=NULL && j<i)   //p为NULL表示i太大;j>i表示i为0;    {        p = p->next;        j++;       //移动指针p,j计数    }    if(j!=i)        return -32768;    else        return p->data;}

2.4 按值查找

LNode *Locate_Node(LNode *L, int key)  //在单链表L中查找值为key的结点{    LNode *p = L->next;    while(p!=NULL && p->data != key)        p = p->next;    if(p->data == key)        return p;    else    {        printf("所要查找的结点不存在!\n");        return NULL;    }}

2.5 插入

/*在以L为头结点的单链表的第i个位置插入值为e的结点*/void Insert_LNode(LNode *L, int i, ElemType e){    int j = 0;    LNode *p, *q;    p = L->next;    while(p!=NULL && j<i-1)    {        p = p->next;        j++;    }    if(j!=i-1)        printf("i太大或i为0!\n");    else    {        q = (LNode *)malloc(sizeof(LNode));        q->data = e;        q->next = p->next;        p->next = q;    }}

2.6 按序号删除

/*删除以L为头结点的单链表中的第i个结点*/void Delete_LinkList(LNode *L, int i){    int j=1;    LNode *p = L, *q = L->next;    while(p->next!=NULL && j<i)    {        p = q;        q = q->next;        j++;    }    if(j!=i)        printf("i太大或i为0!\n");    else    {        p->next = q->next;        free(q);    }}

2.7 按值删除

/*删除以L为头结点的单链表中值为key的第一个结点*/void Delete_LinkList(LNode *L, int key){    LNode *p = L, *q = L->next;    while(q!=NULL && q->data!=key)    {        p = q;        q = q->next;    }    if(q->data == key)    {        p->next = q->next;        free(q);    }    else        printf("所要删除的结点不存在!\n");}
/*按值删除值为key的所有结点*/void Delete_LinkList_Node(LNode *L, int key){    LNode *p = L, *q = L->next;    while(q!=NULL)    {        if(q->data==key)        {            p->next = q->next;            free(q);            q = p->next;        }        else        {            p = q;            q = q->next;        }    }}
/*删除以L为头结点的单链表中所有值相同的结点*/void Delete_Node_value(LNode *L){    LNode *p = L->next, *q, *ptr;    while(p!=NULL)                    //检查链表中所有结点    {        q = p;        ptr = p->next;        while(ptr != NULL)            //检查结点p的所有后继结点ptr        {            if(ptr->data == p->data)            {                q->next = ptr->next;                free(ptr);                ptr = q->next;            }            else            {                q = ptr;                ptr = ptr->next;            }        }        p = p->next;    }}

2.8 合并

/*合并以La,Lb为头结点的两个有序单链表*/LNode *Merge_LinkList(LNode *La, LNode *Lb){    LNode *Lc, *pa, *pb, *pc, *ptr;    Lc = La;    pc = La;    pa = La->next;    pb = Lb->next;    while(pa!=NULL &&pb!=NULL)    {        //将pa所指的结点合并,pa指向下一个结点        if(pa->data < pb->data)        {            pc->next = pa;            pc = pa;            pa = pa->next;        }                //将pb所指的结点合并,pb指向下一个结点        if(pa->data > pb->data)        {            pc->next = pb;            pc = pb;            pb = pb->next;        }                //将pa所指的结点合并,pb所指的结点删除        if(pa->data == pb->data)        {            pc->next = pa;            pc = pa;            pa = pa->next;            ptr = pb;            pb = pb->next;            free(ptr);        }    }        if(pa != NULL)        pc->next = pa;    else        pc->next = pb;   //将剩余的结点链上    free(Lb);    return Lc;}

三、循环链表

判断是否空链表:   head->next == head;
判断是否表尾结点: p->next == head;

四、双向链表

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

4.1 插入

  1. 插入时仅仅指出直接前驱结点,钩链时必须注意先后次序是:“先右后左”。部分语句组如下:
    S = (DulNode *)malloc(sizeof(DulNode));S->data = e;S->next = p->next;p->next->prior = S;p->next = S;S->prior = p;
  2. 插入时同时指出直接前驱结点p和直接后继结点q,钩链时无须注意先后次序。部分语句组如下:

    S = (DulNode *)malloc(sizeof(DulNode));S->data = e;p->next = S;S->next = q;S->prior = p;q->prior = S;

4.2 删除

设要删除的结点为p,删除时可以不引人新的辅助指针变量,可以直接先断链,再释放结点。部分语句组如下:

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


 

原创粉丝点击