线性表的链式表示和实现

单链表的存储结构:

typedef struct LNode{
    ElemType      data;
    struct LNode  *next;
}LNode,*Linklist;

【注1】LNode只是起的一个名字,它并不是一个参数类型,这个名字只代表了一种数据结构。这个数据结构的样式就是花括号里面所括着的那两个成员:一个数据,一个指向下一个同样类型节点的指针。
而typedef struct LNode* LinkList;这一句则是定义了一个名字叫LinkList的指针,这个指针指向一个也属于LNode这种类型数据结构的一个结点。
【注2】
假设L是LinkList型变量,则L为单链表的头指针
假设p是指向线性表中第i个元素(结点a1)的指针,则p->next是指向第i+1个元素(结点ai+1)的指针

带头结点的链表建立(头插法):
这里写图片描述

LinkList CreateList_L(int n){
//创建带头结点的单链表L.
    int x;
    LinkList L;
    LNode *p;
    L=(LinkList)malloc(sizeof(LNode));
    L->next=NULL;
    scanf("%d", &x);  

    for(int i = 1; i <= n ; i++) {
        p=(LNode*)malloc(sizeof(LNode));
        p->data=x;
        p->next=L->next;
        L->next=p;
    }
    return L;
}

带头结点的链表建立(尾插法):
这里写图片描述

LinkList CreateList_L(int n){
//创建带头结点的单链表L.
    int x;
    LinkList L;
    LNode *p,*r=L;//r 为表尾指针
    L=(LinkList)malloc(sizeof(LNode));
    scanf("%d", &x); 

    for(int i = 1; i <= n ; i++) {
        p=(LNode*)malloc(sizeof(LNode));
        p->data=x;
        r->next=p;
        r=p;//r指向新的表尾结点
    }
    r-next=NULL;//尾结点指针置空
    return L;
}
线性表链式表示是一种动态、非连续的存储方式,与顺序表的连续存储不同,它能高效地处理插入删除操作。链式存储通过若干个结点形成链表,下面详细介绍几种常见链表的定义、表示基本操作。 ### 单链表 单链表是结点只有一个指针域的链表。结点是数据元素的存储映像,由数据域指针域两部分组成,链表则是由n个结点通过指针链组成的一个线性表 [^2]。 以下是单链表删除操作的代码示例: ```c Status ListDelete_L(LinkList &L, int i, ElemType &e) { // 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值 LinkList p,q; p = L; int j = 0; while (p->next && j < i-1) { // 寻找第i个结点,并令p指向其前趋 p = p->next; ++j; } if (!(p->next) || j > i-1) return ERROR; // 删除位置不合理 q = p->next; p->next = q->next; // 删除并释放结点 e = q->data; free(q); return OK; } // ListDelete_L ``` 该代码的思路是先找到要删除结点的前一个结点,然后将前一个结点的指针指向要删除结点的下一个结点,最后释放要删除的结点 [^3]。 ### 双链表 双链表是结点有两个指针域的链表。以下是双向链表插入操作的代码示例: ```c int InsertList(LinkList l,int pos,int val){ LinkList p,s; int length,i = 0; length = ListLength(l); p = l; //p初始指向头结点 //判断pos值的合法性 if(pos < 1 || pos > length + 1){ return -1; } while(p != NULL && i < pos - 1){ i++; p = p->next; } //此时p为插入位置的前一个结点 //创建新结点 s = (LinkList) malloc(sizeof(Node)); if(s == NULL){ return -1; } s->data = val; //插入结点 s->next = p->next; if(p->next != NULL){ //若p不为尾结点 p->next->prior = s; } s->prior = p; p->next = s; return 1; //插入成功,返回1 } ``` 此代码实现了在双向链表指定位置插入新结点的功能,先判断插入位置的合法性,然后找到插入位置的前一个结点,创建新结点并调整指针关系 [^4]。 ### 循环链表 循环链表是首尾相接的链表,其特点是从链表中任意一个结点出发都能遍历整个链表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值