线性表之链式存储结构

线性表的顺序存储结构要求逻辑关系上相邻的元素在物理位置上也相邻,这样方便了随机存取,但是在插入和删除元素时,需要移动大量元素,而线性表的链式存储则不要求逻辑上相邻的元素在物理位置上也相邻,在插入和删除元素时比较方便。


单链表可由头指针唯一确定

 C++ Code 
1
2
3
4
typedef struct node{
    int data;   //数据域
    struct node *next;  //指针域,存储下一个结点的地址
}L,*LINK;


通常为了方便对链表进行操作,会在单链表的第一个结点之前附设一个结点,称之为头结点。头结点的数据域可以不存储任何信息,也可以存储如链表的长度等一些附加信息。头结点的指针域指向第一个结点,如果线性表为空,则头结点的指针域为NULL。

定义头指针:

LINK  H;

  线性表之链式存储结构_第1张图片


如上图。H为头结点,数据域不存储数据,指针域指向第一个结点,第一个结点数据域存放第一个数据,指针域指向第二个结点,以此类推,最后一个节点指针域为NULL。

建立链表(后插法)

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
LINK create_List( int a[], int n)
{
    LINK H,p,q;
    H=(LINK)malloc ( sizeof(L));      //申请L型结点存储空间
    p=H;
     for( int i= 0;i<n;i++)
    {
        q=(LINK)malloc ( sizeof(L));
        q->data=a[i];
        p->next=q;
        p=p->next;
    }
    p->next= NULL; //最后一个结点指针域为NULL
     return H;
}

求链表长度

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
int length_List(LINK H)
{
    LINK p=H->next;     //指向第一个结点
    int count=0;        
    while(p)
    {
        p=p->next;
        count++;
    }
    return (count);
}

查找结点:查找链表第k个结点,返回其地址

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
LINK locate_List(LINK H,int k)      //查找链表H的第k个结点的地址
{
    LINK p;
    int j=0;
    p=H->next;      //指向第一个结点
    while(p&&j<k)
    {
        p=p->next;
        j++;
    }
    if(j!=k||!p)
    {
        printf ("参数错误或单链表不存在\n");
        return(NULL);
    }
    return (p);
}

查找元素:根据给出的值,查找对应的结点地址

 C++ Code 
1
2
3
4
5
6
7
LINK locate_L2(LINK H,int x)
{
    LINK p=H->next;
    while(p&&p->data!=x)
        p=p->next;
    return (p);
}

插入元素

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int insert_List(LINK H,int k,int x)     //在链表的第k个结点处插入元素x
{
    LINK p,q;
    p=locate_List(H,k-1);       //找到第k个结点的前驱
    q=(LINK) malloc(sizeof(L));
    if(!q)
    {
        printf ("申请空间失败");
        return(0);
    }
    q->data=x;
    q->next=p->next;        //将数据域为x的结点插入到第k个位置
    p->next=q;
    return 1;
}

删除元素

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int delete_List(LINK H,int k)       //删除给定链表的第K个结点
{
    LINK p,q;
    if(H->next==NULL)
    {
        printf ("链表不存在或空表不能删除");
        return(0);
    }
    p=locate_List(H,k-1);       //找到第k个结点的前驱
    if(p==NULL||p->next==NULL)
    {
        printf ("删除节点输入错误");
        return(0);
    }
    q=p->next;
    p->next=q->next;
    free(q);
    return(1);
}

销毁线性表

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
void destory_List(LINK *H)//头结点地址传递
{
    LINK p,q;
    p=*H;
    while(p)
    {
        q=p;
        p=p->next;
        free(q);
    }
    *H=NULL;
}

应用:求线性表A和B的交集、并集

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void inter_mer(LINK A,LINK B,int m)     
{
    LINK p,q;
    p=A;q=p->next;
    while(q)
    {
        if(!locate_L2(B,q->data ) && m)     //m为1时求A与B的交集,将A在B中不存在的元素结点删除
        {
            p->next =q->next ;
            free(q);
            q=p->next;
        }
        else if(!locate_L2 (B,q->data ) && !m)      //m为0时求A与B的并集,将A在B中不存在的元素结点插入B
        {
            insert_List (B,1,q->data);
            q=q->next ;
        }
        else 
        {
            p=q;
            q=q->next; 
        }
    }
}

说明:m=1时,求线性表A与B的交集,结果保存在线性表A中,
     m=0时,求线性表A与B的并集,结果保存在线性表B中。

你可能感兴趣的:(C语言,存储,指针,单链表,线性表)